1):awk基本控制语句
$1==lead {
printf "\t%s\n",$2
}
$1!=lead {
printf "%s\n",$1
printf "\t%s\n",$2
lead=$1
}
其实也就是模式和命令的格式,即[pattern] {command}。
2):基本的元字符与扩展的元字符
grep与sed使用基本的正则元字符,awk与egrep使用扩展的。
3):*在正则表达式中和普通shell中的区别
[root@oracle ForVMC]# echo h*
h1 h2 h3 h4
下面是正则式中的*号含义:
[root@oracle ForVMC]# wc -l m
4 m
[root@oracle ForVMC]# cat m
h1
h2
h3
h4
[root@oracle ForVMC]# sed -n '/^h.*$/p' m --只要以h开头就行
h1
h2
h3
h4
[root@oracle ForVMC]# sed -n '/^h*$/p' m --行中有任一多的h,包括空行
--这里没有显示行
.和*是基本的正则式(BRE)元素。
4):基本的元字符(BRE)
. 配置除换行符以外的任一字符,但是不能配置换行符(awk中可以)。 ------awk部分
*匹配任一多个在它前面的字符
[]字符类:
[,]与-在[]中的匹配 :
[root@oracle ForVMC]# cat m
]hello-
[root@oracle ForVMC]# grep '^[]cd].*[ba-]$' m
]hello-
[root@oracle ForVMC]# grep '^[]cd].*[-ba]$' m
]hello-
[root@oracle ForVMC]# cat m
[hello-
[root@oracle ForVMC]# grep '^[[cd].*[-ba]$' m
[hello-
就是说如果[,]和-在[]元字符中(些时这两个符号在[]中都有特殊含义),要想把这三个当成是[]成员,则只可以将[,]放在[]最前-放在最后。
匹配[或者]:
[root@oracle ForVMC]# cat m
[hello-.
]yes
[root@oracle ForVMC]# grep '^[][]' m
[hello-.
]yes
另外,所有其它的元字符如果被放在了[]中都将失去元字符的特殊含义,而表示其字面值。
[root@oracle ForVMC]# cat m
[hello-.
]yes
[root@oracle ForVMC]# grep '[.]$' m --这里.被当成字面值
[hello-.
[]在awk中也匹配换行符 ------awk部分
^脱字节,如果不是在[]中就表示行的开始,在[]表示不在[]范围内的。
^在awk中也匹配嵌入的换行符 -------awk部分
$匹配行的结尾
awk中是匹配"字符串"的结尾,即使字符串中有嵌入的换行符 ------awk部分
[root@oracle ForVMC]# cat m
[hello-.
]yes
[root@oracle ForVMC]# grep '\.$' m
[hello-.
[root@oracle ForVMC]# grep '[.]$' m
[hello-.
\{n,m\} 匹配n-m次
记住m是有最大值限制的,可以通过getconf查看相应的最大值。
[root@oracle ForVMC]# cat m
ccababee
mmabdd
[root@oracle ForVMC]# grep '\(ab\)\{2\}' m
ccababee
\是转义符号,也就是转义以上所有的特殊元字符为其字面值。
[root@oracle ForVMC]# cat m
$
^
.
*
[root@oracle ForVMC]# sed -n '/^\$/p;/^\^/p;/^\./p;/^\*/p' m
$
^
.
*
BRE特殊字符汇总:
. ,[] 匹配字符范围
*,\{n,m\}匹配它前面字符次数
^,$行的头和尾
\(\)正则分组,适用于BRE
三类:范围,次数,行头与行尾
5):扩展的元字符(ERE),awk egrep(grep -E)专用
+ 至少一次,*是至少0次
[root@oracle ForVMC]# cat m
ymmoo
ymoo
yoo
[root@oracle ForVMC]# egrep '^ym+o*$' m
ymmoo
ymoo
普通的grep是不能使用+的:
[root@oracle ForVMC]# grep '^ym+o*$' m
[root@oracle ForVMC]# grep -E '^ym+o*$' m --grep -E=egrep,fgrep=grep -F
ymmoo
ymoo
? 匹配0次或者1次(助记:0?还是1?)
[root@oracle ForVMC]# cat m
mmoo
ymoo
[root@oracle ForVMC]# grep -E '^y?' m
mmoo
ymoo
| 关系或
同样用上面的例子
[root@oracle ForVMC]# grep -E '^y|m?' m
mmoo
ymoo
() 对正则表达式分组
{n,m} 用于POSIX的egrep和POSIX的awk,而不是传统的egrep和awk
[root@oracle ForVMC]# cat m
llmmmmtt
lnmmmll
[root@oracle ForVMC]# gawk -W posix '/(mm){2}/ {print $0}' m
llmmmmtt
--gawk -W posix 启动awk 的posix兼容模式
分类:
+,?次数
| (就两种选择),POSIX的{n,m} 范围
() 正则分组,适用于ERE
6): BRE与ERE一点语法比较
[root@oracle ForVMC]# cat m
llmmmmtt
lnmmmll
[root@oracle ForVMC]# sed -n '/\(mm\)\{2\}/p' m
llmmmmtt
[root@oracle ForVMC]# gawk '/\(mm\)\{2\}/ {print $0}' m
[root@oracle ForVMC]# sed -n '/\(mm\)\{2\}/p' m
llmmmmtt
[root@oracle ForVMC]# gawk '/\(mm\)\{2\}/ {print $0}' m
[root@oracle ForVMC]# gawk -W posix '/\(mm\)\{2\}/ {print $0}' m
[root@oracle ForVMC]# gawk -W posix '/(mm){2}/ {print $0}' m
llmmmmtt
当前结论:\(\) \{\}(扩展字符)对应() {}(基本元字符)
匹配():
[root@oracle ForVMC]# cat m
ll(mm)(mm)tt
lnmmmll
[root@oracle ForVMC]# gawk -W posix '/(\(mm\)){2}/ {print $0}' m
ll(mm)(mm)tt
sed不可以用\来转义,但是可以用[]来转义
[root@oracle ForVMC]# sed -n '/\(\(mm\)\)\{2\}/p' m
[root@oracle ForVMC]# sed -n '/\([(]mm[)]\)\{2\}/p' m
ll(mm)(mm)tt
7):实践
\\转义自己:
[root@oracle ForVMC]# cat m
\hello
[root@oracle ForVMC]# sed -n '/\\hello/p' m
\hello
intel处理器匹配:
[root@oracle ForVMC]# cat m
8086
80686
80386
80586
[root@oracle ForVMC]# egrep '80[[:digit:]]?86' m
8086
80686
80386
80586
8):形式化的字符类--POSIX
[:alnum:] 字母和数字
[:digit:] 数字
[:alpha:] 字母
[:xdigit:] 十六进制数
[:lower:] [:upper:]
[:punct:]
以上是常用的
[:blank:] 匹配空格和TAB符
[root@oracle ForVMC]# cat m
[root@oracle ForVMC]# sed 'l' m --sed的l参数可以显示出不可打印字符
\t $
\t是制表符,空格没有显示出来$代表行尾
[:graph:] 匹配可见的,不包括空格
[:space:] 空白字符
[:print:] 可打印的,包括空格
[root@oracle ForVMC]# egrep 'h[[:space:]]+e' m
h e
[root@oracle ForVMC]# egrep 'h[[:print:]]+e' m
h e
[root@oracle ForVMC]# egrep 'h[[:graph:]]+e' m
9):单词的匹配
基本正则式(ERE)\<\>的使用
[root@oracle ForVMC]# cat m
hellbookyy
hello books yy
hello book mm
book yy
[root@oracle ForVMC]# sed -n '/\/p' m
hello book mm
book yy
[root@oracle ForVMC]# egrep '\' m
hello book mm
book yy
[root@oracle ForVMC]# awk '/\/ {print $0}' m
hello book mm
book yy
其实\<\>就是字(word)单位的标识,就像vi可以以字为单位移动一样。
10):TAB与空格的匹配
[root@oracle ForVMC]# cat m
\t
\space
[root@oracle ForVMC]# sed -n '/^\t/p' m
\t
[root@oracle ForVMC]# sed -n '/^ /p' m
\space
\把t的字面值转义成了制表符。
显示行后的空格:
[root@oracle ForVMC]# sed -n 's/ *$/$$/p' m
\space$$
11):awk中的^和$ --awk部分
12):号码格式化
[root@oracle ForVMC]# cat m
05506141423
[root@oracle ForVMC]# sed -n 's/\([[:digit:]]\{4\}\)\([[:digit:]]\{7\}\)/\1-\2/p' m
0550-6141423
13):逻辑或
[root@oracle ForVMC]# cat m
Unix
UNIX
UniX
[root@oracle ForVMC]# egrep 'Unix|UNIX|UniX' m
Unix
UNIX
UniX
[root@oracle ForVMC]# sed -n '/Unix/p;/UNIX/p;/UniX/p' m
Unix
UNIX
UniX
14):正则分组
[root@oracle ForVMC]# cat m
Unix System
Unix
[root@oracle ForVMC]# sed -n '/Unix\( System\)\{0,1\}/p' m
Unix System
Unix
[root@oracle ForVMC]# egrep 'Unix( System)?' m
Unix System
Unix
1):注释#
#n代表sed -n
[root@oracle ~]# cat m
Moon
make
[root@oracle ~]# cat sedscr
#n this is a comment
s/m/l/gp
[root@oracle ~]# sed -f sedscr m
lake
2):替换命令的详细语法
[address]s/pattern/replacement/flag
其中flag可选项:
n 值范围1-512 --指定第起次出现
p --打印模式空间
W file --将模式空间的内容写到file中
g --全局标志
替换命令的定界符可以使用除了换行符外所有字符:
[root@oracle ~]# cat m
Moon
make
[root@oracle ~]# sed -n 's^m^o^p' m
oake
[root@oracle ~]# sed -n 's|m|o|p' m
oake
replacement部分只有下面的内容才具有特殊意义,其它的一切都只有字面含义:
& 引用pattern本身
\n 匹配第n个串,和正则分组\( \)或者ERE的()配合使用
\ 转义符,通常只转义\本身,&和换行符
[root@oracle ~]# sed -n 's!\(Mo\)\(on\)!"\1"\2!p' m
"Mo"on
[root@oracle ~]# sed -n 's!\(Mo\)\(on\)!"\1"\ --这里用来转义换行
> \2!p' m
"Mo"
on
综上:sed 的replacement部分特殊的元字符也只有& \ \n三个,其中在\n中n的范围是1-9
3):指定替换第几个,s命令n的作用
[root@oracle ~]# sed -n 'l;s/\t/TAB/2p' m
\t\tMoon$
TABMoon
make$
4):\n回调正则分组
[root@oracle ~]# cat m
abcdefg
[root@oracle ~]# sed -n 's/\(a\)\(b\)\(c\)\(d\)\(e\)\(f\)\(g\)/\1-\2-\3-\4-\5-\6-\7/p' m
a-b-c-d-e-f-g
5):删除命令d
删除后,模式空间将被清空,所以删除后的命令将不在工作,而是读入下一行。
[root@oracle ~]# cat m
abcdefg
[root@oracle ~]# sed -n 's/a/o/p;/^o/d;p' m
obcdefg
6):追加插入和更改
a(append),i(insert),c(change)
语法:
[address] command\
text
插入是在模式空间前加入内容,追加是在模式空间后,更改是将模式空间内容替换掉。
[root@oracle ~]# sed '/^a/i\
hello' m
hello
abcdefg
[root@oracle ~]# sed '/^a/a\
hello' m
abcdefg
hello
理解a的工作方式:
[root@oracle ~]# cat m
abcdefg
[root@oracle ~]# sed -n '/^a/a\
hello
p
' m
abcdefg
hello
[root@oracle ~]# fc
sed -n '/^a/a\
hello
p
s/h/t/gp' m
abcdefg
hello --只有两行,也就是说hello是在对模式空间运用完所有的命令后,才附加到标准输出内容中的
[root@oracle ~]# fc
sed -n '/^a/a\
hello
p
s/a/t/gp' m
abcdefg
tbcdefg --这一行并不是hello,因为还有命令在处理当前的模式空间
hello --最后附加到标准输出中的
所以可以将a理解为优先级很低的运算符,它通常是最后处理的,不管他出现在什么地方。
i插入也一样:
[root@oracle ~]# sed -n '/^a/i\
> hello
> p
> s/h/t/gp' m
hello
abcdefg
[root@oracle ~]# fc
sed -n '/^a/i\
hello
p
a\
world
s/h/t/gp
s/w/m/gp' m
hello
abcdefg
world
c更改命令更加特殊,它将会把模式空间的内容代替并输出,且运行c命令后模式空间将被清空(这一点和d命令一样),所以它后续的命令都不起作用了。
[root@oracle ~]# sed -n '/^a/c\
why why why' m
why why why
从上面的结果我们还可以得出一个结论:c命令总是包含一个隐匿打印命令,所以可以把c命令理解为:清空模式空间内容并打印给定字符串。
再回过头看看a和i,其实和c一样,不管你有没有指定p命令,它总是输出所指定的内容的:
[root@oracle ~]# sed -n '/^a/a\
> yes' m
yes
7):列表命令l
[root@oracle ~]# cat m
[root@oracle ~]# sed -n 'l' m
\t\t\t\t$
\t\t\t\t$
l命令可以显示出非可见![[:graph:]]字符。
上面的例子中,m中有两行TAB符,第行4个。
8):替换命令y,类似于shell命令tr
[root@oracle ~]# cat m
abcde
[root@oracle ~]# sed -n 'y/abcde/ABCDE/;p' m
ABCDE
9):打印命令p
主要就是一下:普通的打印命令和作为s替换打印命令的区别。
普通打印就是无条件的打印当前模式空间中的内容,而替换命令中的打印命令必须是s成功发生后再执行。
10):打印行号
[root@oracle ~]# sed -n '/^.*/=' m
1
2
3
类似于awk的NR(Row Number)
[root@oracle ~]# gawk '{print NR " " $0}' m
1 abcde
2 ddeed
3 oommt
且只要你在地址后给出了等号,就一定打印行号,不管你有没有指定p命令。
1):n(next)命令
工作模式:打印当前模式空间内容,并清空后立即读入下一行,且读入下一行后不返回命令头,而是继续应用后面的命令。
[root@localhost ~]# cat m
aaaaa
bbbb
[root@localhost ~]# sed -n '/^a/n;s/b/m/gp' m
mmmm
[root@localhost ~]# sed '/^a/n;s/b/m/g' m
aaaaa
mmmm
如果没有指定-n选项,n操作前先打印当前行。
[root@localhost ~]# sed -n 's/b/m/gp;/^a/n;s/b/m/gp' m
mmmm
[root@localhost ~]# sed -n 's/b/o/gp;/^a/n;s/b/m/gp' m
mmmm
上面两条命令证明了n命令不会从头应用命令,而是直接运用后续的命令。
[root@localhost ~]# cat m
aaaaa
bbbb
oooo
mmmm
[root@localhost ~]# sed '/.*/{
n
/^ *$/d
}' m
aaaaa
bbbb
oooo
mmmm
[root@localhost ~]# cat m
aaaaa
bbbb
mmmm
[root@localhost ~]# sed '/.*/{
n
/^ *$/d
}' m
aaaaa
bbbb
mmmm
上面的实践说明了n命令是成对处理行的,所以如果是基数行,一般要用$!n来替换n,关于$!n可以参考后面的。
2):读和写文件
[root@localhost ~]# cat m
aaaaa
bbbb
mmmm
[root@localhost ~]# cat t
Above is a first
[root@localhost ~]# sed -n '/^a/r t' m
Above is a first
和以前的c,a,i命令一样,不管你有没有指定p命令,都会打印非模式空间中的内容。
题外:尾部替换
[root@localhost ~]# sed -n 's/h$/o/gp' m
mmmmho
3):退出命令q
退出命令会立即从sed退出,退出前不做任何事,包括p打印当前模式空间。
head -10 /etc/passwd==sed -n '11q;p' /etc/passwd
1):n(next)命令 工作模式:打印当前模式空间内容,并清空后立即读入下一行,且读入下一行后不返回命令头,而是继续应用后面的命令。
[root@localhost ~]# cat m aaaaa bbbb [root@localhost ~]# sed -n '/^a/n;s/b/m/gp' m mmmm
[root@localhost ~]# sed '/^a/n;s/b/m/g' m aaaaa mmmm
如果没有指定-n选项,n操作前先打印当前行。
[root@localhost ~]# sed -n 's/b/m/gp;/^a/n;s/b/m/gp' m mmmm
[root@localhost ~]# sed -n 's/b/o/gp;/^a/n;s/b/m/gp' m mmmm
上面两条命令证明了n命令不会从头应用命令,而是直接运用后续的命令。
[root@localhost ~]# cat m aaaaa bbbb oooo
mmmm [root@localhost ~]# sed '/.*/{ n /^ *$/d }' m aaaaa bbbb oooo mmmm [root@localhost ~]# cat m aaaaa bbbb
mmmm [root@localhost ~]# sed '/.*/{ n /^ *$/d }' m aaaaa bbbb
mmmm
上面的实践说明了n命令是成对处理行的,所以如果是基数行,一般要用$!n来替换n,关于$!n可以参考后面的。
2):读和写文件
[root@localhost ~]# cat m aaaaa bbbb
mmmm [root@localhost ~]# cat t Above is a first [root@localhost ~]# sed -n '/^a/r t' m Above is a first
和以前的c,a,i命令一样,不管你有没有指定p命令,都会打印非模式空间中的内容。
题外:尾部替换
[root@localhost ~]# sed -n 's/h$/o/gp' m mmmmho
3):退出命令q
退出命令会立即从sed退出,退出前不做任何事,包括p打印当前模式空间。
head -10 /etc/passwd==sed -n '11q;p' /etc/passwd |
阅读(820) | 评论(0) | 转发(0) |