shell三剑客
三剑客的特点:
|
|
|
|
|
|
|
|
|
|
|
|
-
-n:显示行号; -
-i:忽略大小写; -
-o:精准匹配; -
-f:从文件每一行获取匹配模式; -
- c:统计匹配的行数; -
-E:使用扩展正则表达式,相当于egrep; -
-v:反转查找,即输出与查找条件不相符合的行; -
-A:后面可加数字,为 after 的意思,除了列出该行外,后续的 n 行也列出来; -
-B:后面可加数字,为 before 的意思,除了列出该行外,前面的 n 行也列出来; -
-C:后面可加数字,为context 的意思,除了列出该行外,前后的n行也列出来。
2. 示例
# grep “day” a b
# grep -n -f a b
# grep -v -f a b
# echo 'this is a test shell!' |grep -oE "[a-z]+"
# echo 'this is a test' |grep -o 'is'
# ifconfig |grep -E -o "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
sed是一种流编辑器,是非常好用的文本处理工具,配合正则使用更加强大。处理时,把当前处理的行存储在临时的缓冲区中,称为“模式空间”,接着sed命令处理缓冲区的内容,完成后输出到屏幕,接着处理下一行。文件内容没有改变,除非使用-i选项。
1)选项描述
-
-n:不打印模式空间; -
-e:执行脚本、表达式来处理; -
-f:执行动作从文件读取执行; -
-i:修改原文件; -
-r:使用扩展正则表达式。
2)地址描述
-
first~step:步长,每step行,从第first开始;
-
$:匹配最后一行;
-
/regexp/:正则表达式匹配行;
-
number:只匹配指定行;
-
addr1,addr2:开始匹配addr1行开始,直接addr2行结束;
-
addr1,+N:从addr1行开始,向后的N行;
-
addr1,~N:从addr1行开始,到N行结束。
3)地址描述
-
s/regexp/replacement/:替换字符串;
-
p:打印当前模式空间;
-
P:打印模式空间的第一行;
-
d:删除模式空间,开始下一个循环;
-
D:删除模式空间的第一行,开始下一个循环;
-
=:打印当前行号;
-
a:当前行下面追加文本;
-
i:当前行上面插入文本;
-
c:所选行替换新文本;
-
q:立即退出sed脚本;
-
r:追加文本来自文件;
-
: label:label为b和t命令;
-
b label:分支到脚本中带有标签的位置,如果分支不存在则分支到脚本的末尾;
-
t label:如果s///是一个成功的替换,才跳转到标签;
-
h H:复制/追加模式空间到保持空间;
-
g G:复制/追加保持空间到模式空间;
-
x:交换模式空间和保持空间内容;
-
y:把一个字符翻译为另外的字符;
-
l:打印模式空间的行,并显示控制字符$;
-
n N:读取/追加下一行输入到模式空间;
-
w filename:写入当前模式空间到文件;
-
!:取反、否定;
-
&:引用已匹配字符串。
# echo "hello world" | sed 's/ /-/g'
# echo "hello world" | sed 's/world/[&]/'
# sed -e '2,5p' test1
# sed '/he/r test2' test1
# sed '/we/w test3' test1
# sed '/^to/adyz' test1
# sed -i '/he/r test2' test1
# sed 's/century/CENTURY/' test1
# sed -n '1~2p' test1
# sed -n 'p;n' test1
# sed -n '2~2p' test1
# sed -n 'n;p' test1
awk是一个处理文本的编程语言工具,能用简短的程序处理标准输入或文件、数据排序、计算以及生成报表等等。
-
其中pattern表示AWK在数据中查找的内容,而action是在找到匹配内容时所执行的一系列命令。花括号用于根据特定的模式对一系列指令进行分组。
1. 选项
-
-f program-file:从文件中读取awk程序源文件;
-
-F fs:指定fs为输入字段分隔符;
-
-v var=value:变量赋值;
-
--posix:兼容POSIX正则表达式;
-
--dump-variables=[file]:把awk命令时的全局变量写入文件,默认文件是awkvars.out;
-
--profile=[file]:格式化awk语句到文件,默认是awkprof.out。
Pattern |
Description |
BEGIN{ } |
给程序赋予初始状态,先执行的工作 |
END{ } |
程序结束之后执行的一些扫尾工作 |
/regular expression/ |
为每个输入记录匹配正则表达式 |
pattern && pattern |
逻辑and,满足两个模式 |
pattern || pattern |
逻辑or,满足其中一个模式 |
! pattern |
逻辑not,不满足模式 |
pattern1, pattern2 |
范围模式,匹配所有模式1的记录,直到匹配到模式2 |
示例:
# vim test.awk
{print $2}
# tail -n3 /etc/services |awk -f test.awk
# tail -n3 /etc/services |awk '{print $2}'
# tail -n5 /etc/passwd | awk -F ':' '{print $1}'
3.2 工作原理
-
第一步执行BEGIN语句; -
第二步从文件或标准输入读取一行,然后再执行行pattern语句,逐行扫描文件到文件全部被读取; -
第三步执行END语句。
# echo "hello" | awk 'BEGIN{ print "welcome" } {print} END{ print "this is a
# tail /etc/services |awk 'BEGIN{print "Service\t\tPort\t\t\tDescription\n"}{
# echo | awk '{ a="This is"; b="a test"; c="of awk";print a,b,c}'
4. 内置变量
变量名 |
描述 |
$0 |
当前记录 |
$1~$n |
当前记录的第N个字段 |
FS |
输入字段分隔符(-F作用相同)默认空格 |
OFS |
输出字段分隔符,默认是空格 |
RS |
输入记录分隔符,默认换行符\n |
ORS |
输出记录分隔符,默认是换行符\n |
NF |
字段个数/列个数 |
NR |
统计记录编号,每处理一行记录,编号就会+1 |
FNR |
统计记录编号,每处理一行记录,编号也会+1,与NR不同的是,处理第二个文件时,编号会重新计数 |
OFS |
输出字段分隔符,默认空格 |
IGNORECASE |
忽略大小写 |
示例:
# cat test.awk
# awk 'BEGIN{FS=":"}{print $1,$2,$3}'test.awk
# cat test.awk
# awk 'BEGIN{OFS=":"}{print $1,$2,$3}'test.awk
# echo "RS/test/of/awk " | awk 'BEGIN{RS="/"}{print $0}'
将换行(\n)替换为+:
# seq 10 | awk 'BEGIN{ORS="+"}{print $0} END{print "\n"}'
打印字段个数:
# echo "a b c d e f" |awk '{print NF}'
# echo "a b c d e f" |awk '{print $NF}'
打印倒数第二个字段:
# echo "a b c d e f" |awk '{print $(NF-1)}'
# echo "a b c d e f" |awk '{$NF="";$(NF-1)="";print $0}'
# echo "a b c d e f" |awk '{$1="";print $0}'
运算符 |
描述 |
(....) |
分组 |
$ |
字段引用 |
++ -- |
递增和递减 |
+ - ! |
加号,减号,和逻辑否定 |
* / % |
乘,除和取余 |
+ - |
加法,减法 |
| |& |
管道,用于getline,print和printf |
< > <= >= != == |
关系运算符 |
~ !~ |
正则表达式匹配,否定正则表达式匹配 |
in |
数组成员 |
&& || |
逻辑and,逻辑or |
?: |
简写条件表达式: expr1 ? expr2 : expr3 第一个表达式为真,执行expr2,否则执行expr3 |
|
变量赋值运算符 |
示例:
# awk 'BEGIN{a=2;b=3; print a+b }'
# tail /etc/services |awk '!/blp5/{print $0}'
# seq 5 |awk '$0%2==0{print $0}'
# seq 5 |awk '$0%2!=0{print $0}'
# seq 5 |awk '$0~/[34]/{print $0}'
# seq 5 |awk '$0!~/[34]/{print $0}'
# seq 5 |awk '$0~/[^34]/{print $0}'
# awk 'BEGIN{print 1==1?"yes":"no"}'
# awk 'BEGIN{print 1==2?"yes":"no"}'
# seq 5 |awk '{sum+=$0}END{print sum}'
# seq 5 |awk '{if($0==3)print $0}'
# seq 5 |awk '{if($0==3)print $0;else print "no"}'
# awk '{i=1;while(i<=NF){print $i;i++}}' file
# awk '{for(i=1;i<=NF;i++)print $i}' file
# awk 'BEGIN{for(i=1;i<=5;i++){if(i==3){break};print i}}'
# awk 'BEGIN{for(i=1;i<=5;i++){if(i==3){continue};print i}}'