sed
1.正则表达式
sed默认是支持正则表达式的,只不过在命令行使用时需要转义,
echo “aaa bbb “|sed -r ‘s/(.)/A/g’ // -r启用正则表达式
echo “aaa bbb “|sed ‘s/(.)/A/g’ // 不起用正则,则需要转义
AAA AAA
2.替换多个值
echo abc | sed ‘s#(a)#\1\133#’
多次替换,比如将a->1,b->2
sed ‘s/a/1/g; s/b/g/g’ a
3.指定范围
sed ‘1,5{s/a/1/g; s/b/g/g}’ a
awk
1.管道getline
function dofile(fname) {
while (getline <fname > 0) {
if (/^@define[ \t]/) { # @define name value
name = $2
$1 = $2 = ""; sub(/^[ \t]+/, "")
symtab[name] = $0
} else if (/^@include[ \t]/) # @include filename
dofile($2)
else { # Anywhere in line @name@
for (i in symtab)
gsub("@" i "@", symtab[i])
print
}
}
close(fname)
}
BEGIN {
if (ARGC == 2)
dofile(ARGV[1])
else
dofile("/dev/stdin")
}
2.awk管道:同一时刻只能有一个管道
tmpfile= “/tmp/telephone.tmp
for (name in telephone)
print name "/t" telephone[name]>tmpfile
close(tmpfilej
system("sort < tmpfile“)
临时性文件必须在调用system() 之前关闭,以确保任何缓冲区输出都正确地记录在文件内。
先来看个小例子:
echo "21 2
> 3 51
> 17 23"|awk '{
> first[NR]=\$1
> second[NR]=\$2
> }END{
> print "====打印第 1 列并排序:====" >> "testAwkPipe.txt"
> for(i in first){
> print first[i]|"sort -n >> testAwkPipe.txt"
> }
> print "====打印第 2 列并排序:====" >> "testAwkPipe.txt"
> for(j in second){
> print second[j]|"sort -n >> testAwkPipe.txt"
> }
> }'
cat testAwkPipe.txt
====打印第 1 列并排序:====
2
3
17
21
23
51
====打印第 2 列并排序:====
怎么样?结果是不是很诡异呢?这是因为我们在awk中使用了管道后没有close的缘故,这样前一次管道里的数据和文件描述符(指针)还建立着连接,因而,每次排序都是全文排序,下面我们在每个for循环外面加上一句close来关闭管道,看看结果如何:
echo "21 2
> 3 51
> 17 23"|awk '{
> first[NR]=\$1
> second[NR]=\$2
> }END{
> print "====打印第 1 列并排序:====" >> "testAwkPipe.txt"
> for(i in first){
> print first[i]|"sort -n >> testAwkPipe.txt"
> }
> close("sort -n >> testAwkPipe.txt")
> print "====打印第 2 列并排序:====" >> "testAwkPipe.txt"
> for(j in second){
> print second[j]|"sort -n >> testAwkPipe.txt"
}
close("sort -n >> testAwkPipe.txt")
}'> > >
cat testAwkPipe.txt
====打印第 1 列并排序:====
3
17
21
====打印第 2 列并排序:====
2
23
51
现在的结果就是正确的了,这是因为for循环结束后管道里的数据已经和文件断开了连接,每次排序的数据和前一次无关。
3.getline用法
getline < file 从file 文件中,读取下一条记录,存入$0,并更新NF, NR 与FNR
getline var < file 从file 文件中,读取下一条记录,存入var,并更新NF, NR 与FNR
cmd | getline 从外部命令cmd 读取下一条记录,存入$0,并更新NF
cmd | getline var 从外部命令cmd 读取下一条记录,存入var
4.多层管道
awk ‘BEGIN{for(i=0;i<10;i++){print i|“sort | uniq -c > x”}}’