Linux中的常见shell命令(超详细)
目录
给文件赋权限
让 vim 自动添加第一行代码
变量
字符串
参数
shell脚本中的运算符
if语句(流程控制 if else switch)
读取我们控制台的数据命令
循环语句(for循环、while循环)
1)for循环
2) while循环
分支语句中的switch
跳出循环(break contiune)
函数(类似于java中的方法)
数组
脚本文件相互加载
cut --提取,从命令结果中提取对应的内容
sort 排序
1、对字符串进行去重
2、数值类型操作
3、对成绩进行排序
wc (wordcount)--单词统计
split 文件切割
tr 替换和删除
uniq 去重
tee 可以将数据输送到各个文件中 ,跟一个水管一样
脚本后缀sh 和 后缀bash 是一回事,sh 是 bash 的软链接,也就是这两个是一回事
所谓的脚本就是将我们经常使用的linux命令汇总在一个文件中而已。
-
给文件赋权限
最简单的执行命令应该是 ./01.sh
chmod +x 01.sh
付完权限就可以执行了。
-
让 vim 自动添加第一行代码
每次都要创建一个新的文件,比较麻烦,而且每次都要写 #!/bin/bash 这句话
安装vim编辑器:
yum install -y vim在/etc/vimrc文件结尾添加
"#给sh文件添加头部注释
autocmd BufNewFile *.sh exec ":call WESTOS()"
function WESTOS()
call append(0,"#!/bin/bash")
endfunction
autocmd BufNewfile * normal G再次创建一个文件,就会自动添加 #!/bin/bash
-
变量
写法:
your_name="sige" 这个中间不能有空格,变量名和等号之间不能有空格
命名规则:
1、只能是英文字母,数字,和下划线,首个字符不能是数字开头的。
2、中间不能有空格,可以有下划线 错误演示: user name="张三"
3、不能使用标点符号
4、不能使用关键字 bash中的关键字
unset 不能删除 只读变量
-
字符串
在我们的shell编程中,字符串可以使用单引号,双引号,也可以不用任何引号
单引号和双引号的区别:
获取字符串的长度:
skill="java"
echo ${#skill} 打印该字符串的长度
-
参数
$0 表示当前运行的文件名字
$n 表示第n个参数
一定要写在双引号里面例如在脚本文件中输入:
#!/bin/bash
echo "查看shell脚本中的参数"
echo "目前正在执行的脚本的名字是:$0"
echo "获取到的第一个参数是:$1"
echo "获取到的第二个参数是:$2"
echo "获取到的第三个参数是:$3"
echo "获取到的第四个参数是:$4"
#!/bin/bash
echo "第一个参数是$1"
echo "总共有几个参数:$#"
echo "这些参数分别是什么:$*"
echo '验证是否可以使用单引号:$2'
$* 以字符串的形式展示所有的参数
$@ 拿到所有的参数,可以当做一个数组#!/bin/bash
echo '演示$# 和$@的区别'
echo '------------展示$*-------------'
for i in "$*";do
echo $i
done
echo '------------展示$@-------------'
for i in "$@";do
echo $i
done
-
grep 查找内容的
在文件中查找内容
#常规用法:
#grep 内容 路径下的文件
#1.在/etc/passwd文件中,查找'root'
[root@localhost ~]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologinroot' /etc/passwd
#2.在在/etc/passwd文件中,查找'root',并显示行号
[root@localhost ~]# grep -n root /etc/passwd
#3.过滤出passwd文件中的root 不区分大小写
[root@localhost ~]# grep -n -i 'root' /etc/passwd
#取反:
grep -v root /etc/passwd
#***************高级+正则***************
#在/etc/passwd中查找root开始的用户信息;
[root@bigdata01 home]# grep -n '^root' /etc/passwd
不是root开头的:
[root@localhost ~]# grep -nv '^root' /etc/passwd
wc的使用:wordcount
代码:wc test.txt
结果: 4 8 52 test.txt
第一个数字代码:行数
第二个数字代表:单词数量
第三个数字代表:文件大小
– 统计文件的行数:
wc -l filename
比如: wc -l test.txt
– 统计文件的字符数:
wc -c filename
– 统计文件的单词数:
wc -w filename
实战一下:
[root@bigdata01 home]# wc -l test.txt
4 test.txt
[root@bigdata01 home]# wc -w test.txt
8 test.txt
[root@bigdata01 home]# wc -c test.txt
52 test.txt
-
find 查找文件
此处说的查找是指的查找文件,而不是文件里面的内容的。
find 后面有三个参数
-name 根据名字查找
find -name 'init'
-size 根据文件的大小查找
-type 根据文件的类型查找(文件/文件夹/链接)
ll `find /etc -size +200`
第一种查看文件大小的方式。
ll $(find /etc -size +200)
find查找文件:
#语法格式:
find 目录 指定类型 指定名字
#在/etc/目录中找出文件名叫hosts文件
[root@localhost ~]# find /etc -name hosts#在找出/etc/下面以.conf结尾的文件
[root@localhost ~]# find /etc -name *.conf大于 使用+加号 -size +10k 大于10k文件
小于 使用-减号 -size -10k 小于10k文件#3.根据大小找出文件 在/etc/目录下面找出大于10kb的文件
find /etc -size +10k查找出来的内容如何验证是否正确呢?
[root@bigdata01 home]# du -h /etc/postfix/access#未来主要用于查找系统日志文件,旧的日志文件。7天之前的文件
#4.找出/etc/目录下以.conf结尾的,最近7天之前的文件
[root@localhost ~]# find /etc -name *.conf -mtime -7
#5.找出/etc/目录下以.conf结尾的,7天之前的文件
[root@localhost ~]# find /etc -type f -name *.conf -mtime +7查找出来的文件如何知道是正确的呢?
stat 验证
stat 文件名 可以查看这个文件的所有详细信息
[root@bigdata01 home]# stat /etc/chrony.conf
由以上 时间轴可以看出,最右边为当前时,+5 代表大于等于 6 天前的文件名, -5 代表小于等于 5 天内的文件名, 5 则是代表 5-6 那一天的文件名。
#6.找出/etc/中以.conf结尾大于10kb修改时间是7天之前的文件
[root@localhost ~]# find /etc -name *.conf -mtime +7 -size +10k
#7.查找文件的时候指定最多找多少层目录
#-maxdepth 1 选项位置第1个,指定find命令查找的最大深度,不加上就是所有层。
find / -maxdepth 2 -type f -name "*.conf"
[root@localhost ~]# find / -maxdepth 2 -name "*.conf"
-maxdepth 属性不能在 name 之后,否则报错!!!
#8.结合``符号案例,目标将所有查询的文件以列表形式显示,类似于ll
[root@bigdata01 home]# ls -l `find /etc -maxdepth 2 -name *.conf -mtime +7 -size +10k`
#下述方式也可以
[root@bigdata01 home]# ls -l $(find /etc -maxdepth 2 -name *.conf -mtime +7 -size +10k)不是所有命令都可以使用管道符来解决:
[root@bigdata01 home]# find /etc -maxdepth 2 -name *.conf -mtime +7 -size +10k | ls -l查找出来的结果就是错误的。
#解决方案:xargs 参数传递,主要让一些不支持管道的命令可以使用管道技术
[root@bigdata01 home]# find /etc -maxdepth 2 -name *.conf -mtime +7 -size +10k | xargs ls -l
#理解xargs把前面命令传递过来的字符串转换为后面命令可以识别的参数。
#温馨提示: |xargs后面无法使用 ll,它是别名。还可以这么干:
#exec方式(了解即可)
[root@bigdata01 home]# find /etc -maxdepth 2 -name *.conf -mtime +7 -size +10k -exec ls -l {} ;
-exec选项用于对每个找到的文件执行指定的命令。在这个例子中,-exec ls -lh {} ;表示对于每个匹配到的.conf文件,执行ls -lh命令来显示其详细信息。
此时的h 意思是将文件大小表示为可阅读的格式
具体来说,{}是一个占位符,代表当前找到的文件路径。;是-exec选项的结束标志。
-
shell脚本中的运算符
shell和其他的编程一样,是支持运算的,但是我们的bash 不支持。
我们可以借助 expr 这个表达式工具完成,数据之间的加减乘除运算。
bash中也可以不使用expr 进行运算
可以使用(()) $(()) $[] 进行算数运算
((a++)) 可以执行类似于这样的运算
将两个值进行运算 $((3 + 5))
a=2
b=3
$((a + b)) // 可以
$(($a + $b)) //也可以
-
if语句(流程控制 if else switch)
if语句的语法:
if condition; then
command1
command2
...
commandN
fiif else 的语法:
if condition; then
command1
command2
...
commandN
else
command
fi
例如:
#!/bin/bash
a=20
if [ $a -gt 10 ];then
echo "a的值大于10"
fi#编写条件的时候,使用[] 里面的代码跟[] 之间有空格,否则报错!
#!/bin/bash
a=$1
if [ $a -gt 10 ];then
echo "a大于10"
else
echo "a 小于等于10"
fi
关系运算符的一些转换字符
运算符 | 说明 | 英文 | 举例 |
-eq | 检测两个数是否相等,相等返回 true。 | equal | [ b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | not equal | [ b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | greater than | [ b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | less than | [ b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | Greater than or equal to | [ b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | Less than or equal to | [ b ] 返回 true。 |
案例:
#!/bin/bash
a=$1
b=$2
if [ $a -gt $b ];then
echo "a大于b"
fi
if [ $a -lt $b ];then
echo "a 小于 b"
fi
if [ $a -eq $b ];then
echo "a等于b"
fi
举例:
#!/bin/bash
name=$1
if [ $name -eq 123 ]; then
echo '登录成功'
else
echo '登录失败'
fi# -eq 只能比较数值类型,字符串类型比较使用 = 或者 ==
#!/bin/bash
name=$1
password=$2
if [ $name == 'root' ] && [ $password -eq 123456 ];then
echo "账号和密码正确"
else
echo "账号密码错误,请重试"
fi
-
读取我们控制台的数据命令
read -p "请输入您的姓名:" name
echo $name
例如:
编写一个脚本,提示请输入用户名 ,请输入密码,假如用户名是root 密码是123456
提示登录成功,否则显示登录失败。
#!/bin/bash
read -p "请输入用户名:" name
read -p "请输入密码:" password
if [[ $name = 'root' && $password = '123456' ]]; then
echo "登录成功"
else
echo "登录失败"
fi#比较数字,使用 -eq
#比较字符串 使用 = 或者 ==
#假如有多个条件,使用 [[ ]]
-
循环语句(for循环、while循环)
1)for循环
语法:
for 变量 in (list); do
// 编写执行的语句
done
案例:
#!/bin/bash
#打印数组[12345]
for i in 1 2 3 4 5;do
echo $i
done
#输出0到100之间10的倍数
for i in {1..100};do
if [ $[ i % 10 ] -eq 0 ]; then
echo $i
fi
done
#输出0到100之间10的倍数另一种格式
for i in {1..100};do
if (( (i % 10) == 0 )); then
echo $i
fi
done
#输出0到100步长为2即(1,3...97,99)之间的数
for i in {1..100..2};do
echo "奇数为:$i"
done
#输出0到100之间的偶数
for i in {1..100};do
if [ $[i%2] -eq 0 ];then
echo $i
fi
done
echo "--------给一个目录下的所有文件赋权限---------"
for file in `ls /home/scripts`;do
echo $file
chmod u+x $file
done
#累加1到5
#!/bin/bash
num=0
for i in 1 2 3 4 5;do
num=$[i+num]
done
echo $num
以上这个 for 循环类似于我们 java 中的 foreach 循环(加强for),还有一种 for(int i=0;i<100;i++)
案例:使用 for i 循环,计算 1+... 100
#!/bin/bash
sum=0
for((i=1;i<=100;i++));do
sum=$[sum+i]
done
echo "总和是$sum"
2) while循环
语法:
while 条件; do
执行语句
done// 死循环
while true; do
执行语句
done
案例:
#1~100之间相加
#!/bin/bash
echo "--------for循环版本-----------"
num=0
for i in {1..100};do
num=$[num+i]
done
echo "结果为$num"
echo "----------while循环--------------"
sum=0
i=1
while [ $i -le 100 ];do
sum=$[sum+i]
((i++))
done
echo "计算结果为:$sum"
// 每隔一秒钟打印一个当前时间
#!/bin/bash
while true; do
date
sleep 1
done
-
分支语句中的switch
switch 写法其实是if 写法的一个 语法糖(有他没他都无所谓)
语法:
case 值 in
匹配的值1)
执行语句
;;
匹配的值2)
执行语句
;;
...
esac
案例:
#在控制台输入数据 1~7,如果是1 打印星期一#!/bin/bash
echo "请输入1~7之间的数字"
read num
case $num in
1) echo "星期一"
;;
2) echo "星期二"
;;
3) echo "星期三"
;;
4) echo "星期四"
;;
5) echo "星期五"
;;
6) echo "星期六"
;;
7) echo "星期日"
;;
esac
#!/bin/bash
read -p "请输入你喜欢的季节:" season
case $season in
"春天")
echo "春天可以放风筝" ;;
"夏天")
echo "夏天可以吃西瓜" ;;
"秋天")
echo "秋天可以吃很多水果" ;;
"冬天")
echo "冬天可以吃火锅" ;;
esac
-
跳出循环(break contiune)
break 跳出所有的循环
continue 跳出本次循环
break 跳出所有的循环
案例:
#每隔1s打印时间,当打印到第10次的时候,跳出该循环
#!/bin/bash
i=1
while true; do
date
sleep 1
if [ $i -eq 10 ];then
break
fi
((i++))
done
continue 跳出本次循环,进入下一个循环
案例:
#打印1~100之间不是10的倍数的数字
#!/bin/bash
for i in {1..100}; do
if test $[ i % 10 ] -eq 0; then
continue
fi
echo $i
done#!/bin/bash
echo "打印1~100之间不是10的倍数的数字"
for i in {1..100};do
if [ $[i%10] -ne 0 ];then
echo $i
else
continue
fi
done
test的用法:
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
数字比对:
num1=100
num2=100
if test $num1 -eq $num2
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi字符串比较:
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi文件的操作:【很重要】
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
if 后面的判断,判断之后可以省略 分号; 但是 then 需要换行才行。
-
函数(类似于java中的方法)
语法:
function 方法名()
{
//执行语句
[return xxx;]
}
快速定义个方法,然后执行:
这些都写在脚本里
#!/bin/bash
function showName()
{
echo "该方法被执行了"
}showName
定义有参的方法:
function func2()
{
echo "$0可以得到什么?"
echo "获取第一个参数$1"
echo "获取第二个参数$2"
echo "参数的个数$#"
echo "所有参数有$*"
echo "所有参数第二种方式:$@"
}
func2 1 100 1000
方法可以有返回值:
参数的返回: return 返回值
#!/bin/bash
function showName(){
echo "你调用了这个方法"
echo "第一个参数$1"
echo "第二个参数$2"
return $[ $1 + $2 ]
}
showName 110 119
val=$?
echo $val风凉话:假如两个值的结果大于了255,也不准了。
想要返回值是字符串,做梦,可以通过打印来解决,一般没有返回值的话,返回最后的输出结果。
function validateStr(){
echo "abc"
}
vvv=`validateStr`
echo $vvv
-
数组
bash中,只支持一维数组,不支持多维数据。
一维:
[1,2,3,4]
二维:
[
[1,2.3],
[2,3,4]
]
数组的名字=(val1 val2 val3 ...)
my_arr=(a b c d "E") 定义数组,并且赋值。
//直接通过下标赋值
my_arr2[0]=hello
my_arr2[1]=world
my_arr2[2]=java
数组的循环:
第一种方式类似于:foreach
#!/bin/bash
my_arr=(AA BB CC)
for str in ${my_arr[*]}
do
echo $str
done
第二种使用下标的方式 :
#!/bin/bash
my_arr=(AA BB CC)
length=${#my_arr[*]}
for((i=0;ido
echo ${my_arr[$i]}
done
循环中,不是用$符号也可以的。
-
脚本文件相互加载
类似于java语言中的 import加载库
a.sh 中定义了一个数组,b.sh中直接使用
案例:
a.sh中直接定义个数组
#!/bin/bash
echo "我是a脚本文件:"
my_arr=(AA BB CC)
#b.sh中使用a.sh中的数组(使用之前要加载,类似于java中的导包)
#!/bin/bash
source ./a.sh #加载文件中的内容for str in ${my_arr[*]}
do
echo $str
done
-
cut --提取,从命令结果中提取对应的内容
cut 后面的 -c 的意思是按照字符选取内容
参数 | 英文 |
-d '分隔符' | delimiter |
-f n1,n2 | fields |
参数 | 英文 | 含义 |
-c | characters | 按字符选取内容 |
范围控制:
范围 | 含义 |
n | 只显示第n项 |
n- | 显示 从第n项 一直到行尾 |
n-m | 显示 从第n项 到 第m项(包括m) |
案例:
准备数据 1.txt
111:aaa:bbb:ccc
222:ddd:eee:fff
333:ggg:hhh
444:iii
案例:
1、提取1.txt中前两行的第五个字符
head -2 1.txt // 查看文件的前两行
head -2 1.txt | cut -c 5cut 本身也可以直接提取内容
cut -c 5 1.txt2、截取1.txt文件中前两行以:进行分割的1,2,3段内容
head -2 1.txt | cut -d ':' -f 1,2,3
head -2 1.txt | cut -d ':' -f 1-3将处理好的数据放入一个文件中:
head -2 1.txt | cut -d ":" -f 1,2,3 >> 111.txthead -2 1.txt | cut -d ":" -f 2-
-
sort 排序
准备数据:2.txt
banana
apple
pear
orange
pear
1、对字符串进行去重
参数 | 英文 | 含义 |
-u | unique | 去掉重复的 |
2、数值类型操作
对数值类型进行的操作
参数 | 英文 | 含义 |
-n | numeric-sort | 按照数值大小排序 |
-r | reverse | 使次序颠倒 |
将 1.txt 中 第二列数据,倒序排列
[root@bigdata01 datas]# cut -d ":" -f 2 1.txt | sort -r
准备数据:3.txt
1
3
5
7
11
2
4
6
10
8
9
3、对成绩进行排序
参数 | 英文 | 含义 |
-t | field-separator | 指定字段分隔符 |
-k | key | 根据哪一列排序 |
造数据: 4.txt
zhangsan 68 99 26
lisi 98 66 96
wangwu 38 33 86
zhaoliu 78 44 36
maqi 88 22 66
zhouba 98 44 46
需求:根据第二个成绩进行倒序排序:
结合cut 的做法:
cut -d ' ' -f 3 4.txt | sort -r -ncat 4.txt | sort -t ' ' -k 3
sort -t ' ' -k 3 4.txt
-
wc (wordcount)--单词统计
wc 跟上文件名 显示文件的字节数,单词数,文件的行数
造数据:5.txt
111
222 bbb
333 aaa bbb
444 aaa bbb ccc
555 aaa bbb ccc ddd
666 aaa bbb ccc ddd eee
如果只想显示某一些数据:
参数 | 英文 | 含义 |
-c | bytes | 字节数 |
-w | words | 单词数 |
-l | lines | 行数 |
wc -l 5.txt
wc -l 1.txt 2.txt 3.txt 4.txt 5.txt
wc -l *.txt
我想看一下某个文件夹下有多少个文件:
ls /etc | wc -w
ll /etc | wc -l[root@bigdata01 scripts]# num=$[`ll | wc -l`-1]
[root@bigdata01 scripts]# echo $num
28
[root@bigdata01 scripts]# echo $[`ll | wc -l`-1]
28
-
split 文件切割
创造数据:拷贝一个/etc/services
cp /etc/services $PWD
mv services big.txt
ll 查看文件的大小
按照字节进行切割:
split -b 100k big.txt
split -l 3000 big.txt
查看大小:
du -h /home/scripts/datas/xaa ==100k
ll
wc -c 文件名
删除所有的 x开头的文件
rm -rf ./x*
查看一个文件中有多少行
wc -l xaa
-
tr 替换和删除
语法:tr 被替换的字符 新字符 是translate 的缩写
替换文件中所有的小写字母为大写字母并查看:
cat 8.txt | tr '[a-z]' '[A-Z]'
替换:
删除操作:
使用tr 进行一个单词计数的练习:
造一个数据:
9.txt
hello,world,hadoop
hive,sqoop,flume,hello
kitty,tom,jerry,world
hadoop
第一种方案:
[root@bigdata01 scripts]# cat 9.txt | tr ',' ' '|wc -w
12第二种方案:
将单词中的,替换为换行符
cat 9.txt | tr ',' ' '
//接着使用排序,去重等操作
cat 9.txt | tr ',' ' ' | sort | uniq
// 接着可以进行单词重复记录的数据
cat 9.txt | tr ',' ' ' | sort | uniq -c也可以这么写:
cat 9.txt | tr ',' ' ' | sort -u | wc -l
-
uniq 去重
uniq 命令用于检查及删除文本文件中重复出现的行,一般与 sort 命令结合使用
cat 10.txt | sort | uniq
-
tee 可以将数据输送到各个文件中 ,跟一个水管一样
cat 10.txt | sort | uniq -c | tee a.txt b.txt c.txt
查看一个文件夹中所有文件的大小:
du -h *
或者
du -h -a