shell 脚本常用命令参考
shell 脚本常用命令参考
[root@test475 ~]# find . -name "*.txt" -o -name "*.cfg"
emacs posix-basic 不能实现下面的表达式
posix-awk posix-egrep posix-extended 可以实现下面的表达式
[root@test475 ~]# find . -regextype posix-egrep -regex ".*(.txt|.pdf)"
#
[root@test475 ~]# find . -regextype posix-extended -regex ".*(.txt|.pdf)"
#
[root@test475 ~]# find . -regextype posix-awk -regex ".*(.txt|.pdf)"
文件名与正则表达式模式匹配。这是整个路径上的匹配,而不是搜索。
例如,要匹配名为 ./fubar3'的文件,您可以使用正则表达式'.* bar。'
或 ".* b.* 3"
但不是 'f.* r3'
。 find理解的正则表达式默认为Emacs Regular表达式,但可以使用-regextype选项进行更改。
[root@test475 ~]# find . -regextype emacs -regex ".*a.txt"
./aa.txt
[root@test475 ~]# find . -regextype emacs -iregex ".*a.txt"
./AAA.txt
./aa.txt
[root@test475 ~]# find . ! -name "*.txt" -print
.
./.bash_logout
./anaconda-ks.cfg
./aaaa.pdf
[root@test475 ~]# find . ! -name "*.txt"
.
./.bash_logout
./anaconda-ks.cfg
./aaaa.pdf
[root@test475 ~]# find . -maxdepth 1 -type f
./.bash_logout
./.bash_profile
./.bashrc
./.cshrc
./.tcshrc
./anaconda-ks.cfg
./.bash_history
./aaaa.pdf
./ccccc.pdf
./AAA.txt
./BBB.txt
./.lesshst
./.viminfo
./aa.txt
./bb.txt
./cc.txt
./bbbbb.pdf
./ddddd.pdf
[root@test475 ~]# find . -maxdepth 1 -type f
./aa.txt
./bb.txt
./cc.txt
[root@test475 ~]# find . -maxdepth 2 -type f
./aa.txt
./bb.txt
./cc.txt
./tmp/1.txt
./tmp/2.txt
./tmp/3.txt
[root@test475 test]# ll
总用量 1128
-rw-r--r-- 1 root root 2097152 4月 22 21:39 black
lrwxrwxrwx 1 root root 5 4月 22 21:39 mnt -> /mnt/
drwxr-xr-x 2 root root 6 4月 22 21:32 test01
[root@test475 test]# find . -type d -print
.
./test01
[root@test475 test]# find . -type l -print
./mnt
[root@test475 test]# find . -type f -print
./black
[root@test475 test]# find . -atime 1 -type f -print
相关信息
-atime:访问时间(单位是天,分钟单位是 -amin ,以下类似)
-mtime:修改时间(内容被修改)
-ctime:变化时间(元数据或权限变化)
#大于2M 的文件。
[root@test475 test]# find . -size +2M
./10M
#查找777 权限
[root@test475 test]# find . -perm 777 -print
#查找 chrony 用户的文件
[root@test475 test]# find / -user chrony -type f -print
#删除
[root@test475 test]# find . -type f -name "*a" -delete
#必须以 \;结尾,且 \ 与 {} 之间有空格。{}是特殊字符串。
[root@test475 test]# find . -type f -user root -exec chown user {} \;
#调用脚本
[root@test475 test]# find -type f -exec ./test.sh {} \;
#匹配包含 root 的行并显示,-c 统计行数,-o 只输出匹配的文本行(匹配到的次数,每次一行),-v 只输出不匹配的行
[root@test475 ~]# grep root /etc/passwd
#统计匹配到的行数
[root@test475 ~]# grep -c "root" /etc/passwd
2
[root@test475 ~]# grep -o "root" /etc/passwd
root
root
root
root
[root@test475 ~]# grep -n "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
# -l 适合查找文件,配合 -R 使用
[root@test475 ~]# grep -l "root" /etc/passwd
/etc/passwd
[root@test475 ~]# cat aa.txt
aa
Aaaa
Bac
[root@test475 ~]# grep -Rl "Aaa" .
./aa.txt
[root@test475 ~]# echo aaa > bb.txt
# -i 忽略大小写
[root@test475 ~]# grep -Rli "Aaa" .
./.bash_history
./aa.txt
./bb.txt
# 多重匹配(或)
[root@test475 ~]# grep -e "aa" -e "Ba" aa.txt
aa
Aaaa
Bac
#xargs
[root@test475 ~]# grep "a" b* -Z | xargs -0
bb.txt aaa
[root@test475 ~]# grep "a" b* -lZ | xargs -0
bb.txt
#使用 xargs 删除 bb.txt
[root@test475 ~]# grep "a" b* -lZ | xargs -0 rm
xargs 命令行参数转换
xargs 能够将输入数据转换为特定命令行参数;这样可以配合很多命令来组合使用。比如 grep,比如 find ;
#将多选输出转化为单行输出。
[root@test475 ~]# cat bb.txt
aaa
aa
bb
cc
[root@test475 ~]# cat bb.txt | xargs
aaa aa bb cc
[root@test475 ~]#
# xargs -n 指定每行显示的字段数
[root@test475 ~]# cat bb.txt | xargs -n 3
aaa aa bb
cc
xargs 参数说明
-d 定义定界符(默认为空格)
-n 每行字段数
-I {} 指定替换字符串,这个字符串在 xargs 扩展时被替换掉,用于待执行的命令需要多个参数时
[root@test475 ~]# grep root /etc/passwd | xargs -I '{}' echo '{haha}'
{haha}
{haha}
[root@test475 ~]# grep root /etc/passwd | xargs -I '{}' echo '{}'
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
# -0 输入定界符
[root@test475 ~]# find . -type f -name "*.txt" -print0
./AAA.txt./BBB.txt./bb.txt./cc.txt./tmp/1.txt./tmp/2.txt./tmp/3.txt./tmp/4.txt
[root@test475 ~]# find . -type f -name "*.txt" -print0| xargs -0
./AAA.txt ./BBB.txt ./bb.txt ./cc.txt ./tmp/1.txt ./tmp/2.txt ./tmp/3.txt ./tmp/4.txt
[root@test475 ~]# find . -type f -name "*.txt" -print0| xargs -0 wc -l
0 ./AAA.txt
0 ./BBB.txt
5 ./bb.txt
0 ./cc.txt
0 ./tmp/1.txt
0 ./tmp/2.txt
0 ./tmp/3.txt
0 ./tmp/4.txt
5 总用量
[root@test475 ~]#
sort 排序,默认为增序列
- -n 按数字,-d 按字典
- -r 逆序排序
- -k N 指定按第几列
uniq 消除重复
uniq -c
统计行数
uniq -d
找出重复
uniq -s
开始位置,-w
比较位数
[root@test475 ~]# cat test.txt
12345678
12345678
12345687
12387654
12395432
[root@test475 ~]# uniq test.txt -s 4 -w 2
12345678
12387654
12395432
[root@test475 ~]# uniq test.txt -s 6 -w 2
12345678
12345687
12387654
12395432
tr 进行转换
#加密
[root@test475 ~]# echo 12345 | tr '0-9' '9876543210'
87654
#tab 变空格
[root@test475 ~]# echo 12345 | tr '' ' '
# -d 删除字符
[root@test475 ~]# cat test.txt
123fd4fdf5678
1234ssa56fd78
[root@test475 ~]# cat test.txt | tr -d '0-9'
fdfdf
ssafd
-c
求补集
-d -c
删除非数字数据
[root@test475 ~]# cat test.txt | tr -c -d '0-9'
1234567812345678123456871238765412395432
#tr 压缩字符
[root@test475 ~]# cat test.txt
12vvc395bcc432
[root@test475 ~]# cat test.txt | tr -s 'v'
12vc395bcc432
字符类
--- | --- |
---|---|
alnum | 字母和数字 |
alpha | 字母 |
digit | 数字 |
space | 空白字符 |
lower | 小写 |
upper | 大写 |
cntrl | 控制(非可打印)字符 |
可打印字符 |
使用方法:tr [:lower] [:upper]
# cut 按列切分文本
[root@test475 ~]# cut -d: -f2,4 /etc/passwd
x:0
x:1
#显示去除指定列的所有列
[root@test475 ~]# cut -d: -f1 --complement /etc/passwd
x:0:0:root:/root:/bin/bash
-d
指定定界符
取值范围,配合 -f
使用
N-
第N个到结尾
-M
第一个到M 个
N-M
第N个到M
[root@test475 ~]# grep root /etc/passwd | cut -d : -f -3
root:x:0
operator:x:11
[root@test475 ~]# grep root /etc/passwd | cut -d : -f 3-
0:0:root:/root:/bin/bash
11:0:operator:/root:/sbin/nologin
[root@test475 ~]# grep root /etc/passwd | cut -d : -f 6-8
/root:/bin/bash
/root:/sbin/nologin
[root@test475 ~]#
cut 取的单位
-b
以字节为单位
-c
以字符为单位
-f
以字段为单位(使用定界符,默认为空格)
[root@test475 ~]# grep root /etc/passwd | cut -c 6-8
x:0
tor
[root@test475 ~]# grep root /etc/passwd | cut -c 1-8
root:x:0
operator
paste 按列拼接文本
[root@test475 ~]# cat file1
1
2
[root@test475 ~]# cat file2
a
b
[root@test475 ~]# paste file1 file2
1 a
2 b
#-d 指定定界符
[root@test475 ~]# paste file1 file2 -d ';'
1;a
2;b
[root@test475 ~]# paste file1 file2 -d ":"
1:a
2:b
[root@test475 ~]#
wc -l file #统计行数
wc -w file #统计单词数
wc -c file #统计字符数
[root@test475 ~]# cat test.txt
This is test txt.
Please input num:
print output num:
[root@test475 ~]# wc -l test.txt
3 test.txt
[root@test475 ~]# wc -w test.txt
10 test.txt
[root@test475 ~]# wc -c test.txt
54 test.txt
[root@test475 ~]#
sed 文件替换
#替换每行第一个匹配到的"u"为"a"
[root@test475 ~]# sed 's/u/a/' test.txt
This is test txt.
Please inpat num:
print oatput num:
#全文替换
[root@test475 ~]# sed 's/u/a/g' test.txt
This is test txt.
Please inpat nam:
print oatpat nam:
#-i 直接修改
[root@test475 ~]# cat test.txt
This is test txt.
Please input num:
print output num:
[root@test475 ~]# sed -i 's/\./\:/g' test.txt
[root@test475 ~]# cat test.txt
This is test txt:
Please input num:
print output num:
# G 在匹配内容后加入空行
[root@test475 ~]# sed -i '/txt/G' test.txt
[root@test475 ~]# cat test.txt
This is test txt:
Please input num:
print output num:
#删除空行
[root@test475 ~]# sed '/^$/d' test.txt
This is test txt:
Please input num:
print output num:
#已匹配的字符串通过标记& 来引用:
[root@test475 ~]# echo "this is an example" | sed 's/\w\+/[&]/g'
[this] [is] [an] [example]
#字串匹配标记
[root@test475 ~]# cat aa.txt
123456
abc123
abc456 abc789
[root@test475 ~]# sed 's/abc[0-9]//' aa.txt
123456
23
56 abc789
[root@test475 ~]# sed 's/abc[0-9]//g' aa.txt
123456
23
56 89
#sed 双引号支持变量
[root@test475 ~]# p=patten
[root@test475 ~]# r=replaced
[root@test475 ~]# echo "line con a patten " | sed "s/$p/$r/g"
line con a replaced
[root@test475 ~]#
#PEKSHA 转 PEK/SHA
[root@test475 ~]# cat bb.txt
peksha
shamd5
[root@test475 ~]# sed 's/^.\{3\}/&\//g' bb.txt
pek/sha
sha/md5
[root@test475 ~]#
awk数据流处理工具
awk ' BEGIN {statements} statements2 END {statements} '
工作方式
- 执行 begin 中语句块;
- 从文本或 stdin 中读入一行,然后执行 statements2,重复这个过程,直到文件全部被读取完毕;
- 执行 end 语句块;
print打印当前行
使用不带参数的 print 时,会打印当前行;
[root@test475 ~]# echo "line1 line2" | awk 'BEGIN {print "start"} {print } END {print "end"}'
start
line1 line2
end
print 以逗号分割时,参数以空格定界;
[root@test475 ~]# echo | awk '{var1="v1";var2="v2";var3="v3";print var1,var2,var3;}'
v1 v2 v3
使用 –
拼接
[root@test475 ~]# echo | awk '{var1="v1";var2="v2";var3="v3";print var1"-"var2"-"var3;}'
v1-v2-v3
特殊变量: NR NF $0
$1
$2
NR 表示记录数量,在执行过程中对应当前行号;
NF 表示字段数量,在执行过程中总对应当前行的字段数;
$0
这个变量包含执行过程中当前行的文本内容
$1
第一个字段内容;
$2
第二个字段内容;以此类推
[root@test475 ~]# echo "line1 f2 f3 line2 line 3" | awk '{print NR ":" $0"-"$1"-"$2}'
1:line1 f2 f3 line2 line 3-line1-f2
#打印每行的第二和第三个字段
[root@test475 ~]# cat awk
1 2 3
4 5 6
7 8 9
[root@test475 ~]# awk '{print $2 ,$3}' awk
2 3
5 6
8 9
#统计文件行数
[root@test475 ~]# awk 'END {print NR}' awk
3
#累加一每一行的第一个字段:
[root@test475 ~]# awk 'BEGIN {num=0;print "begin";} {sum+=$1;} END {print "==" ;print sum}' awk
begin
12
样式对awk 处理进行过滤
awk 'NR<5'
awk 'NR==1,NR==4 {print}' file #行号等于1和4的打印出来
awk '/linux/' #包含 linux
awk '!/linux/' #不包含 linux
设置定界符 -F
awk -F : '{print $NF}' /etc/passwd
读取命令输出
[root@test475 ~]# echo | awk '{"grep root /etc/passwd" | getline cmdout;print cmdout}'
root:x:0:0:root:/root:/bin/bash
awk 中使用循环
#以逆序的形式打印行
[root@test475 ~]# seq 9 | awk '{lifo[NR] = $0;lno=NR}END {for(;lno>-1;lno--){print lifo[lno]};}'
9
8
7
6
5
4
3
2
1
awk 实现 head 和 tail 命令
#head:
awk 'NR<=10{print}' filename
#tail
[root@test475 ~]# awk '{buffer[NR%10]=$0}{i=NR%10}END {for(i=NR+1;i<NR+11;i++){print buffer[i%10]}}' filename
打印指定列
#awk 实现方式
[root@test475 ~]# ls -lrt | awk '{print $6}'
#cut 方式实现,未实现 ls 的截取
打印指定文本区域
#确定行号
[root@test475 ~]# seq 100 | awk 'NR==4,NR==6{print}'
4
5
6
#确定文本
#打印处理 Startpattern 和 endpatten 之间的文本;
[root@test475 ~]# seq 100 | awk '/13/,/15/'
13
14
15
[root@test475 ~]# cat /etc/passwd | awk '/mai.*mail/,/ftp.*ftp/'
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@test475 ~]#
awk 常用内建函数
index(string,search_string):返回 search_string在 string 中出现的位置
sub(regex,replacement_str,string):将正则匹配到的第一处内容替换为 replacement_str
match(regex,string):检查正则表达式是否能够匹配字符串
length(string):返回字符串长度
[root@test475 ~]# echo | awk '{"grep root /etc/passwd" | getline cmdout;print length(cmdout)}'
31
printf 类似 c 语言中的Printf,对输出进行格式化
[root@test475 ~]# seq 10 | awk '{printf "->%4s",$1}'
-> 1-> 2-> 3-> 4-> 5-> 6-> 7-> 8-> 9-> 10
迭代文件中的行、单词和字符
1、迭代文件中的每一行
#while 循环法
while read line;
do
echo $line
done <file.txt
改成子shell :
cat file.txt | (while read line;do echo $line;done)
awk 法
cat file.txt | awk '{print}'
2、迭代第一行中的每一个单词
for word in $line
do
echo $word
done
3、迭代每一个字符
${string:startpos:numof_chars}:从字符串中提取一个字符;(bash 文本切片)${#word};返回变量word的长度
for((i=0;i<${#word};i++))
do
echo ${word:i:1}
done