月度热点

网络推荐



本广告位招租!

推荐给好友 上一篇 | 下一篇

《SED 单行脚本快速参考》的 awk 实现

BSD爱好者乐园w!We}6a2a4IY4H`

sedawk 都是 Linux 下常用的流编辑器,他们各有各的特色,本文并不是要做什么对比,而是权当好玩,把《SED 单行脚本快速参考》这文章,用 awk 做了一遍~ 至于孰好孰坏,那真是很难评论了。一般来说,sed 的命令会更短小一些,同时也更难读懂;而 awk 稍微长点,但是 if、while 这样的,逻辑性比较强,更加像“程序”。到底喜欢用哪个,就让各位看官自己决定吧!

;v2_(pNj4]

2e(vw:q|
n2y;fI8uFhh文本间隔:

(Q2gg ]M~/fx

3c+@,f#EwL# 在每一行后面增加一空行

T cb0m?*P|O

#~ uuK%L M#K6o$\?q ~/Msed GBSD爱好者乐园p1Itq'~Y.X4PN
awk '{printf("%s\n\n",$0)}'
cQ8KT0W Et3L(_# 将原来的所有空行删除并在每一行后面增加一空行。
(a A$U(T#y6P# 这样在输出的文本中每一行后面将有且只有一空行。BSD爱好者乐园V6nW4X-UQ"B:M5kD

.cj1A,S[O2y(msed '/^$/d;G'
mw(Y9DCH/Q i @awk '!/^$/{printf("%s\n\n",$0)}'
cvmbuES1vCpV8k`# 在每一行后面增加两行空行

0Yi Ke.XAe

8py0P d0@7b6tTx@sed 'G;G'
u(I#~m{$Fawk '{printf("%s\n\n\n",$0)}'
"D uAD@:W)T0F-w'S \# 将第一个脚本所产生的所有空行删除(即删除所有偶数行)BSD爱好者乐园 n%oR T|6p-[m

(@:L2Me2iBvsed 'n;d'BSD爱好者乐园/]AcX-xE
awk '{f=!f;if(f)print $0}'BSD爱好者乐园 d m&Y,Z6n
# 在匹配式样“regex”的行之前插入一空行

&^%~#| Y V1D

f3O#L(@:]y_4jsed '/regex/{x;p;x;}'
Bh_4gk2?4M%aawk '{if(/regex/)printf("\n%s\n",$0);else print $0}'
Wp]YB$M_B# 在匹配式样“regex”的行之后插入一空行BSD爱好者乐园 O3iO?!D.q

BSD爱好者乐园^:^(d$Wh S

sed '/regex/G'BSD爱好者乐园*er Md$kv$P
awk '{if(/regex/)printf("%s\n\n",$0);else print $0}'BSD爱好者乐园 pYqky+D
# 在匹配式样“regex”的行之前和之后各插入一空行BSD爱好者乐园4T"V,NT)nc'^d kE

BSD爱好者乐园)S-SI(e3iG A

sed '/regex/{x;p;x;G;}'
X{[ @6t:vfawk '{if(/regex/)printf("\n%s\n\n",$0);else print $0}'
{y)bC(Q&jTl编号:BSD爱好者乐园}$o\6O+\.[

)q)d p.tg5?C# 为文件中的每一行进行编号(简单的左对齐方式)。这里使用了“制表符”BSD爱好者乐园1`Rb"_q+gcfqGA
# (tab,见本文末尾关于’\t’的用法的描述)而不是空格来对齐边缘。

8u2RyQ.N4A"j%pBSD爱好者乐园 b,_8o&n-Y Wm+__

sed = filename | sed 'N;s/\n/\t/'BSD爱好者乐园 n PQ$c~#n8a [
awk '{i++;printf("%d\t%s\n",i,$0)}'
1|&Fk X'{%r# 对文件中的所有行编号(行号在左,文字右端对齐)。

kgQ%B f \&X

Mj(D8H D Dl:~sed = filename | sed 'N; s/^/     /; s/ *\(.\{6,\}\)\n/\1  /'BSD爱好者乐园} a'M M!~[_
awk '{i++;printf("%6d  %s\n",i,$0)}'BSD爱好者乐园SWM B*X_ p
# 对文件中的所有行编号,但只显示非空白行的行号。BSD爱好者乐园l3myu2Y0^#KU j

S]$Q!qoR!r&vsed '/./=' filename | sed '/./N; s/\n/ /'BSD爱好者乐园%yD&N6g$D
awk '{i++;if(!/^$/)printf("%d %s\n",i,$0);else print}'BSD爱好者乐园8FSq;j4Z
# 计算行数 (模拟 “wc -l”)BSD爱好者乐园i.F;?T8?j M"}aN

BSD爱好者乐园)G:h-o;{Jx+r I)S6T

sed -n '$='
(V;D"jZB*Om.d6s \!iDawk '{i++}END{print i}'
&A0EF;F@文本转换和替代:BSD爱好者乐园/L!f5z;g$@gIjyJ

{'F ? u(J6O sWLp# Unix环境:转换DOS的新行符(CR/LF)为Unix格式。

a!s$uR ]&kBSD爱好者乐园K&]d5j2`:Sjd+Z%E`A

sed 's/.$//'                     # 假设所有行以CR/LF结束BSD爱好者乐园0s[*t$V;Q*T7v&C-x
sed 's/^M$//'                    # 在bash/tcsh中,将按Ctrl-M改为按Ctrl-V
W5S,V+i8i`-Ased 's/\x0D$//'                  # ssed、gsed 3.02.80,及更高版本BSD爱好者乐园F0PJ4f(T8N
awk '{sub(/\x0D$/,"");print $0}'BSD爱好者乐园nER4O%I-cG P
# Unix环境:转换Unix的新行符(LF)为DOS格式。BSD爱好者乐园x.\5`+|rb-T

]3xbDC'F5fsed "s/$/`echo -e\\\r`/"        # 在ksh下所使用的命令
5a/WE{a ^#K{$Dsed 's/$'"/`echo\\\r`/"         # 在bash下所使用的命令
w V^ Y4W)pS|e DPFsed "s/$/`echo\\\r`/"           # 在zsh下所使用的命令
Ei,H"No f"kFsed 's/$/\r/'                    # gsed 3.02.80 及更高版本
{ o9r;u;q-`,e[&Rawk '{printf("%s\r\n",$0)}'
'a9[j.a.}_*w&qq# DOS环境:转换Unix新行符(LF)为DOS格式。BSD爱好者乐园'V ?2],i5s u!iRv

BSD爱好者乐园)l9_J*Uh

sed "s/$//"                      # 方法 1
g7KP B MUsed -n p                         # 方法 2
,i U.^];MjDDOS环境的略过

k5l/wP'o`Zz[8K"m

8].ngZ-D6KgNG F# DOS环境:转换DOS新行符(CR/LF)为Unix格式。BSD爱好者乐园1Z8O/iC6N i%_5[,i){
# 下面的脚本只对UnxUtils sed 4.0.7 及更高版本有效。要识别UnxUtils版本的BSD爱好者乐园#rFAZw)[
# sed可以通过其特有的“–text”选项。你可以使用帮助选项(“–help”)看
OJl|?:M l# 其中有无一个“–text”项以此来判断所使用的是否是UnxUtils版本。其它DOSBSD爱好者乐园|`.B.S5d9vf"Y `@Z
# 版本的的sed则无法进行这一转换。但可以用“tr”来实现这一转换。

m9TZ:wWG%JS7k(?BSD爱好者乐园9Pt#w-ex

sed "s/\r//" infile >outfile     # UnxUtils sed v4.0.7 或更高版本
Vs(Ei,Il2Ktr -d \r <infile >outfile        # GNU tr 1.22 或更高版本BSD爱好者乐园bk5Ga'n3pV9| oL
DOS环境的略过BSD爱好者乐园o:Qw:H;htM}{

BSD爱好者乐园,QT BInB

# 将每一行前导的“空白字符”(空格,制表符)删除
m0]\ E k}p# 使之左对齐

J5Scv_wm)c@

$Zg:H[xom vi$v.dsed 's/^[ \t]*//'                # 见本文末尾关于'\t'用法的描述
9}5E@7v$UX ^Ri!uawk '{sub(/^[ \t]+/,"");print $0}'BSD爱好者乐园*q\0euE6w
# 将每一行拖尾的“空白字符”(空格,制表符)删除

F)F y sU1eJ!wBSD爱好者乐园*aWg m+K\

sed 's/[ \t]*$//'                # 见本文末尾关于'\t'用法的描述
-W0h Y/E:[M3rawk '{sub(/[ \t]+$/,"");print $0}'BSD爱好者乐园{0a-Q9]*P-Q Y
# 将每一行中的前导和拖尾的空白字符删除

5[$w-}%_-FJ:sBSD爱好者乐园8a;YI wVi8mBQ7S*P

sed 's/^[ \t]*//;s/[ \t]*$//'BSD爱好者乐园GG)DO`q;l @"\%] w
awk '{sub(/^[ \t]+/,"");sub(/[ \t]+$/,"");print $0}'BSD爱好者乐园3{ u)E V_
# 在每一行开头处插入5个空格(使全文向右移动5个字符的位置)BSD爱好者乐园0J.W f(m7@Bi![$gB)q

BSD爱好者乐园@.t N3a0M/^X4I

sed 's/^/     /'
xJD3V/L~`h'\awk '{printf("     %s\n",$0)}'BSD爱好者乐园v.q1_#K)R-FWK
# 以79个字符为宽度,将所有文本右对齐
KP_0f#{,x8Kn%jM# 78个字符外加最后的一个空格BSD爱好者乐园q[o9[7`0? l

?w3V%~`sed -e :a -e 's/^.\{1,78\}$/ &/;ta'BSD爱好者乐园'Fa|~A*gpv(kR
awk '{printf("%79s\n",$0)}'
:V6SJy#wN3J5^# 以79个字符为宽度,使所有文本居中。在方法1中,为了让文本居中每一行的前BSD爱好者乐园O%ciQ9Kej N
# 头和后头都填充了空格。 在方法2中,在居中文本的过程中只在文本的前面填充
)n"R/o~5a]A8I4y A# 空格,并且最终这些空格将有一半会被删除。此外每一行的后头并未填充空格。

y0Kj)UB-cBSD爱好者乐园0}L {N eV"?+n_-u

sed  -e :a -e 's/^.\{1,77\}$/ & /;ta'                     # 方法1
(E$?k7t$aE5i1mlsed  -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/'  # 方法2BSD爱好者乐园%|,J|p;`6qOU^
awk '{for(i=0;i<39-length($0)/2;i++)printf(" ");printf("%s\n",$0)}'  #相当于上面的方法二BSD爱好者乐园 p"zlq%K KT7m
# 在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”

9hs(J hl }~u5l

S| r;uODPsed 's/foo/bar/'                 # 只替换每一行中的第一个“foo”字串BSD爱好者乐园@I/u?`!GR,f
sed 's/foo/bar/4'                # 只替换每一行中的第四个“foo”字串
p3Dk"x1Aksed 's/foo/bar/g'                # 将每一行中的所有“foo”都换成“bar”
5^ Yn^&]Pmnsed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # 替换倒数第二个“foo”BSD爱好者乐园1p7M~&O6a
sed 's/\(.*\)foo/\1bar/'            # 替换最后一个“foo”BSD爱好者乐园xQ$U^6r#q4F o |fb{
awk '{gsub(/foo/,"bar");print $0}'   # 将每一行中的所有“foo”都换成“bar”BSD爱好者乐园*q3ZjuY-{'z4f
# 只在行中出现字串“baz”的情况下将“foo”替换成“bar”BSD爱好者乐园0| G,u[%bA

BSD爱好者乐园0Ik2Wy6~+?U(hY

sed '/baz/s/foo/bar/g'BSD爱好者乐园g'k0nl~A3J
awk '{if(/baz/)gsub(/foo/,"bar");print $0}'
3~-nd.I)[:R# 将“foo”替换成“bar”,并且只在行中未出现字串“baz”的情况下替换

.AJu2I-KBSD爱好者乐园1OL.T"wBt/c

sed '/baz/!s/foo/bar/g'BSD爱好者乐园7r%w0M9B}&tb"`
awk '{if(/baz$/)gsub(/foo/,"bar");print $0}'BSD爱好者乐园#n*Ei$r7@ kd
# 不管是“scarlet”“ruby”还是“puce”,一律换成“red”

2tne^no6^

1[F _ x&X2mAtsed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g'  #对多数的sed都有效BSD爱好者乐园E#x~.H1I:q
gsed 's/scarlet\|ruby\|puce/red/g'               # 只对GNU sed有效BSD爱好者乐园|3O(F+^6pK
awk '{gsub(/scarlet|ruby|puce/,"red");print $0}'BSD爱好者乐园f'rD5V3Tr1[(hE]
# 倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)。BSD爱好者乐园Youq(Z'`+I1N7{
# 由于某些原因,使用下面命令时HHsed v1.5会将文件中的空行删除

:A(l6_4d)J

L8_!fz'v-Esed '1!G;h;$!d'               # 方法1
ii#S/k7vsed -n '1!G;h;$p'             # 方法2BSD爱好者乐园*{W1z3a:Z {7m5S
awk '{A[i++]=$0}END{for(j=i-1;j>=0;j--)print A[j]}'BSD爱好者乐园-g K3Z%}7bZ
# 将行中的字符逆序排列,第一个字成为最后一字,……(模拟“rev”)

5U3e BI.B8d GBSD爱好者乐园/b6b6b ]?S;U-s

sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
@0YV5k"p2vEyawk '{for(i=length($0);i>0;i--)printf("%s",substr($0,i,1));printf("\n")}'BSD爱好者乐园/D)g-u\ee'O5?4_E
# 将每两行连接成一行(类似“paste”)BSD爱好者乐园 zq.G A1}S-~A:X9L

?7u m \;j!|R1Xsed '$!N;s/\n/ /'
_(Z1K oWX Yawk '{f=!f;if(f)printf("%s",$0);else printf(" %s\n",$0)}'BSD爱好者乐园9m|?;eM6rE s z
# 如果当前行以反斜杠“\”结束,则将下一行并到当前行末尾
!U@5D5T,JP8s# 并去掉原来行尾的反斜杠

ljf$ALYBSD爱好者乐园(p,`b)ZO+[u G td

sed -e :a -e '/\\$/N; s/\\\n//; ta'BSD爱好者乐园.W+[3iW`
awk '{if(/\\$/)printf("%s",substr($0,0,length($0)-1));else printf("%s\n",$0)}'BSD爱好者乐园m1W ] v8X`Q%]+V
# 如果当前行以等号开头,将当前行并到上一行末尾BSD爱好者乐园)mQ ~zM |$h`+G
# 并以单个空格代替原来行头的“=”

Sd9W;M ^]-y"n0^AV c

;u!_*Lv-y Wsed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
$]"sq'k Gawk '{if(/^=/)printf(" %s",substr($0,2));else printf("%s%s",a,$0);a="\n"}END{printf("\n")}'BSD爱好者乐园]3f u#BPg L5W-e]
# 为数字字串增加逗号分隔符号,将“1234567”改为“1,234,567”BSD爱好者乐园 tL x3F)Me0c.Q5?-o&w

p?lMk,YEMgsed ':a;s/\B[0-9]\{3\}\>/,&/;ta'                     # GNU sedBSD爱好者乐园 Z*E,h4A c.A!Y
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'  # 其他sedBSD爱好者乐园vn3_+oK@ ogp
#awk的正则没有后向匹配和引用,搞的比较狼狈,呵呵。

c3W9v$E4_ {^ W

#K:x)Lh I Xawk '{while(match($0,/[0-9][0-9][0-9][0-9]+/)){$0=sprintf("%s,%s",substr($0,0,RSTART+RLENGTH-4),substr($0,RSTART+RLENGTH-3))}print $0}'
a]b-c R&i`(\# 为带有小数点和负号的数值增加逗号分隔符(GNU sed)BSD爱好者乐园Kon.j5f9Jx

BSD爱好者乐园"i(?ic?

gsed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta'
paDv*`Z#和上例差不多

Z)BQ$z ^,j` ]

!fU B.eGs M3Nawk '{while(match($0,/[^\.0-9][0-9][0-9][0-9][0-9]+/)){$0=sprintf("%s,%s",substr($0,0,RSTART+RLENGTH-4),substr($0,RSTART+RLENGTH-3))}print $0}'
M;O:kPSs^,z]?# 在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)BSD爱好者乐园 p2T!CW nn }

BSD爱好者乐园p3c*P!aM j'r

gsed '0~5G'                      # 只对GNU sed有效
D i!D1D^9J+nsed 'n;n;n;n;G;'                 # 其他sed
y a$bt#I ZU~awk '{print $0;i++;if(i==5){printf("\n");i=0}}'
UjFKi_|a.C选择性地显示特定行:BSD爱好者乐园^O Z:H+aN

BSD爱好者乐园h1Pw;@:Q m&V

# 显示文件中的前10行 (模拟“head”的行为)

u7Q q } UL$T~ YYBSD爱好者乐园.~ C-YJ,Eg@

sed 10q
U0VP)L:Q GdE$z'Hawk '{print;if(NR==10)exit}'BSD爱好者乐园*^b.OnO
# 显示文件中的第一行 (模拟“head -1”命令)

`d7}rfh sqBSD爱好者乐园w#\ vB1|:V'C

sed q
(jweXEk!?9Aawk '{print;exit}'BSD爱好者乐园4y7d AY4\i1C)d1O
# 显示文件中的最后10行 (模拟“tail”)BSD爱好者乐园4dTB*S3K$r:kJ J@

BSD爱好者乐园G w[7m8plkb3X v w8t

sed -e :a -e '$q;N;11,$D;ba'
4N:E5Yr*w#用awk干这个有点亏,得全文缓存,对于大文件肯定很慢

:D^V#`(M[$O tV5A

o2bmI8C/t u'@awk '{A[NR]=$0}END{for(i=NR-9;i<=NR;i++)print A[i]}'BSD爱好者乐园6W9kK,Z?F
# 显示文件中的最后2行(模拟“tail -2”命令)

$kK'KJ{prL r

OIWn&~%})Rcsed '$!N;$!D'
-wJ(~E8x5?.^b Hawk '{A[NR]=$0}END{for(i=NR-1;i<=NR;i++)print A[i]}'BSD爱好者乐园0|x$HU5EVR Y
# 显示文件中的最后一行(模拟“tail -1”)

d h1t:{HwO6a5SBSD爱好者乐园"h:K)J8N:I

sed '$!d'                        # 方法1
\$V/J!`;q po%rHsed -n '$p'                      # 方法2
t+Hm|i*[!FgK5Rv#这个比较好办,只存最后一行了。BSD爱好者乐园Q/h\&^#fBo%hsp

a^K |%ecxawk '{A=$0}END{print A}'
'z(dm)Bm*p^# 显示文件中的倒数第二行

1b%[8ZhK5^2n|BSD爱好者乐园qc5wmqc]

sed -e '$!{h;d;}' -e x              # 当文件中只有一行时,输出空行BSD爱好者乐园1ac9\9pmd
sed -e '1{$q;}' -e '$!{h;d;}' -e x  # 当文件中只有一行时,显示该行
;ye"F.q.t3}Qsed -e '1{$d;}' -e '$!{h;d;}' -e x  # 当文件中只有一行时,不输出
p*[R1G'qS,z#存两行呗(当文件中只有一行时,输出空行)

k9s5mr#jX/T4K IBSD爱好者乐园;cc3K4{0j+Q

awk '{B=A;A=$0}END{print B}'BSD爱好者乐园H:c9e I"d-Ia
# 只显示匹配正则表达式的行(模拟“grep”)BSD爱好者乐园&Bt'[bkGalS

Z$Hp0b/msed -n '/regexp/p'               # 方法1
Nb3T[ |3D$Rsed '/regexp/!d'                 # 方法2
"F4g$t(B4p;E&b^awk '/regexp/{print}'BSD爱好者乐园j vZ%D;z5T3c l)V
# 只显示“不”匹配正则表达式的行(模拟“grep -v”)

%C:pz y6HC-^2y)p0NBSD爱好者乐园[,f8W.kbf

sed -n '/regexp/!p'              # 方法1,与前面的命令相对应
AZW!sLHf5CQ(y!psed '/regexp/d'                  # 方法2,类似的语法
"Q `-M%e,Cc lawk '!/regexp/{print}'BSD爱好者乐园/^ kXem R*BOj
# 查找“regexp”并将匹配行的上一行显示出来,但并不显示匹配行BSD爱好者乐园7F'~[%I/CS#Iv z2an;C

c-@"Ug1~7[:T'l`9e]sed -n '/regexp/{g;1!p;};h'BSD爱好者乐园qEI,fIIN8H
awk '/regexp/{print A}{A=$0}'BSD爱好者乐园7C x k4EU'Q
# 查找“regexp”并将匹配行的下一行显示出来,但并不显示匹配行BSD爱好者乐园+{nI,J/nR~9ge ^

BSD爱好者乐园:vE)k-kv-@t%LX#E

sed -n '/regexp/{n;p;}'BSD爱好者乐园1t-|-w In(C6^
awk '{if(A)print;A=0}/regexp/{A=1}'BSD爱好者乐园.[)]Br q/X!NkS4E:g
# 显示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所在行的行号 (类似“grep -A1 -B1”)BSD爱好者乐园&]C]3OY9K8s

BSD爱好者乐园#e4w,V'u+A P

sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
$u(]z2y b}awk '{if(F)print;F=0}/regexp/{print NR;print b;print;F=1}{b=$0}'BSD爱好者乐园iRrEMxB/Q\
# 显示包含“AAA”、“BBB”和“CCC”的行(任意次序)BSD爱好者乐园7hc\8h&Y!l

BSD爱好者乐园Vw;E&q0L:C

sed '/AAA/!d; /BBB/!d; /CCC/!d'   # 字串的次序不影响结果
^.Et4Y mh(Mawk '{if(match($0,/AAA/) && match($0,/BBB/) && match($0,/CCC/))print}'
cK7wv _6[-~O)O#~o# 显示包含“AAA”、“BBB”和“CCC”的行(固定次序)BSD爱好者乐园,CcL i'c)~(p

BSD爱好者乐园0BiFja&s,sY\

sed '/AAA.*BBB.*CCC/!d'
EL$I"v:w;Nawk '{if(match($0,/AAA.*BBB.*CCC/))print}'BSD爱好者乐园RD7t.^1{;w
# 显示包含“AAA”“BBB”或“CCC”的行 (模拟“egrep”)BSD爱好者乐园*s9{&wD ];Iw/~2UcW

BSD爱好者乐园6Vg8K5r"hI

sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d    # 多数sed
:y2cx~5ZTgsed '/AAA\|BBB\|CCC/!d'                        # 对GNU sed有效
N C*]2^Q x6mawk '/AAA/{print;next}/BBB/{print;next}/CCC/{print}'BSD爱好者乐园!A6XK rvtk*BV b
awk '/AAA|BBB|CCC/{print}'BSD爱好者乐园a.F.k~M$X
# 显示包含“AAA”的段落 (段落间以空行分隔)
(`%Y7Jxde K7^%t7ei# HHsed v1.5 必须在“x;”后加入“G;”,接下来的3个脚本都是这样

k6_#S!@Q r%J

/Kf ?qk:dsed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'BSD爱好者乐园T&ZhH;|
awk 'BEGIN{RS=""}/AAA/{print}'
w%kuN8xwUtBawk -vRS= '/AAA/{print}'
$] V,[\K-fQ# 显示包含“AAA”“BBB”和“CCC”三个字串的段落 (任意次序)

t.N{J QV r4f~BSD爱好者乐园%Hgs u&J8J ~W

sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
P n0LYK.oNawk -vRS= '{if(match($0,/AAA/) && match($0,/BBB/) && match($0,/CCC/))print}'BSD爱好者乐园8a d'rK0{-Q-eZW
# 显示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)

6vpB'cv`mQ)izz

7v(@,U J-DUK]sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
I3_&`3t3v.k wFgsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d'         # 只对GNU sed有效
+e0g/u` J2]awk -vRS= '/AAA|BBB|CCC/{print "";print}'BSD爱好者乐园+KL{0[fpu
# 显示包含65个或以上字符的行

VG#b^VxBSD爱好者乐园j+te_5PDW&G;[1V

sed -n '/^.\{65\}/p'BSD爱好者乐园,V{%rJN
cat ll.txt | awk ‘{if(length($0)>=65)print}’

3a3^6hj#K"v

WMB!e?cuY)?'^# 显示包含65个以下字符的行BSD爱好者乐园}4JF{X9@hr

o6sL2``*x/LUsed -n '/^.\{65\}/!p'            # 方法1,与上面的脚本相对应
(E(F!X7\ tsed '/^.\{65\}/d'                # 方法2,更简便一点的方法
~q:hL(X9O9@*]awk '{if(length($0)<=65)print}'BSD爱好者乐园;lo'Ia)ik:pAu
# 显示部分文本——从包含正则表达式的行开始到最后一行结束BSD爱好者乐园i |]!@dL O7V#~ zc

BSD爱好者乐园|#I|(N8iV/?

sed -n '/regexp/,$p'
R/c&^'G:qoawk '/regexp/{F=1}{if(F)print}'BSD爱好者乐园&aQ.af{"x|a)`n
# 显示部分文本——指定行号范围(从第8至第12行,含8和12行)

`!j%x-^,`o:aBSD爱好者乐园Z n@ C?_(]

sed -n '8,12p'                   # 方法1
3X"A"G&T._(DIsed '8,12!d'                     # 方法2
bqqvR8q(DTawk '{if(NR>=8 && NR<12)print}'BSD爱好者乐园1y#a!_.NhpA;N
# 显示第52行BSD爱好者乐园 v6h5j2O K

BSD爱好者乐园 QXf fN

sed -n '52p'                     # 方法1BSD爱好者乐园Q@'Y Q^gn
sed '52!d'                       # 方法2BSD爱好者乐园@,A)C{$JZK
sed '52q;d'                      # 方法3, 处理大文件时更有效率
I?PGU:Z e Vawk '{if(NR==52){print;exit}}'BSD爱好者乐园 C D?.} f
# 从第3行开始,每7行显示一次BSD爱好者乐园;g#g t&G%[+Mn/I

BSD爱好者乐园4gz4T5K'xp4|ILR#R

gsed -n '3~7p'                   # 只对GNU sed有效BSD爱好者乐园_\)W5ra
sed -n '3,${p;n;n;n;n;n;n;}'     # 其他sedBSD爱好者乐园(mj k4ziB.i0]AfY
awk '{if(NR==3)F=1}{if(F){i++;if(i%7==1)print}}'
'snW{ nPr7Z3I# 显示两个正则表达式之间的文本(包含)

2U D)dy:P!]5U^BSD爱好者乐园 L jh {E-ixIz

sed -n '/Iowa/,/Montana/p'       # 区分大小写方式BSD爱好者乐园gF;dR!c m@!n"vq!]
awk '/Iowa/{F=1}{if(F)print}/Montana/{F=0}'
%B q2@+Lv0wt选择性地删除特定行:BSD爱好者乐园U'sL#T/N] S&Bd

BSD爱好者乐园6k8St8N"D

# 显示通篇文档,除了两个正则表达式之间的内容BSD爱好者乐园ns e1J&Grqv

BSD爱好者乐园+|/O+zC+^[?

sed '/Iowa/,/Montana/d'
O C(T/@`Z8Isawk '/Iowa/{F=1}{if(!F)print}/Montana/{F=0}'BSD爱好者乐园7`Ab'wH B ZL+w$r
# 删除文件中相邻的重复行(模拟“uniq”)
:|k iR4n&tw# 只保留重复行中的第一行,其他行删除BSD爱好者乐园~'w,\ vU(k O

4^YAl0b;T0lnsed '$!N; /^\(.*\)\n\1$/!P; D'BSD爱好者乐园@eMC[)U'L
awk '{if($0!=B)print;B=$0}'BSD爱好者乐园[za1JcDK+]2t
# 删除文件中的重复行,不管有无相邻。注意hold space所能支持的缓存大小,或者使用GNU sed。BSD爱好者乐园u ^E7?{](] o&f

BSD爱好者乐园4cf&u1pS-CO}

sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'  #bones7456注:我这里此命令并不能正常工作BSD爱好者乐园%mBu AapT n|c
awk '{if(!($0 in B))print;B[$0]=1}'BSD爱好者乐园 R4g{1oz&I&]1`3~
# 删除除重复行外的所有行(模拟“uniq -d”)

f?jO3f7@"}BSD爱好者乐园0E:L(R!W0noT;K.i

sed '$!N; s/^\(.*\)\n\1$/\1/; t; D'BSD爱好者乐园*S9`3Hoi
awk '{if($0==B && $0!=l){print;l=$0}B=$0}'
0\_Y-g_-d!nE# 删除文件中开头的10行

TeDo4NsC8Z

.n4x@PXsed '1,10d'
S0K#p4m{[awk '{if(NR>10)print}'
)RB.q,b8e5]8]M# 删除文件中的最后一行

s!~x0V8},@1^:j |q

0C5i1_U-_sed '$d'
"q,ep.hkH N!J*f#awk在过程中并不知道文件一共有几行,所以只能通篇缓存,大文件可能不适合,下面两个也一样

!jRW@5|&zXOBSD爱好者乐园|n2dEnRo-T

awk '{B[NR]=$0}END{for(i=0;i<=NR-1;i++)print B[i]}'BSD爱好者乐园"ca+@S Z-b*K-M0n Z`W)C
# 删除文件中的最后两行

N8Md b:o

5Y n8BSv#ssed 'N;$!P;$!D;$d'
O7cRje(o-q.]Vawk '{B[NR]=$0}END{for(i=0;i<=NR-2;i++)print B[i]}'
4V8Q?o qf# 删除文件中的最后10行BSD爱好者乐园+D#qnbGw

_h%~ Y KSsed -e :a -e '$d;N;2,10ba' -e 'P;D'   # 方法1
2M5}wC7`hzTnsed -n -e :a -e '1,10!{P;N;D;};N;ba'  # 方法2BSD爱好者乐园)z_?y*`](TN:^0_
awk '{B[NR]=$0}END{for(i=0;i<=NR-10;i++)print B[i]}'
#G6n {T@# 删除8的倍数行

8o#V*kz9BV

njP Z;ogsed '0~8d'                           # 只对GNU sed有效BSD爱好者乐园,it7eu Y|\ m*sjO$_
sed 'n;n;n;n;n;n;n;d;'                # 其他sedBSD爱好者乐园@%H+{c [w
awk '{if(NR%8!=0)print}' |head
+x7hls)jv JK}-{# 删除匹配式样的行BSD爱好者乐园]rZ9[Zc"~f)x&m;h?

|5P/u@ Db)Gi Psed '/pattern/d'                      # 删除含pattern的行。当然pattern可以换成任何有效的正则表达式BSD爱好者乐园 ZG#_`q3u2B
awk '{if(!match($0,/pattern/))print}'
!m@5k\`%T$UC# 删除文件中的所有空行(与“grep ‘.’ ”效果相同)

l)?1uTL,`&q^ ya

Xg nYQsed '/^$/d'                           # 方法1
g'YX h |'used '/./!d'                           # 方法2BSD爱好者乐园-vG.X_ci\#|M3J9l
awk '{if(!match($0,/^$/))print}'BSD爱好者乐园Wb XI AG
# 只保留多个相邻空行的第一行。并且删除文件顶部和尾部的空行。BSD爱好者乐园/LY:l'L~)c2P
# (模拟“cat -s”)

O+u|w,O_iD`q B

t3@9c5HY6hF"fKRsed '/./,/^$/!d'        #方法1,删除文件顶部的空行,允许尾部保留一空行BSD爱好者乐园4V+cP t1zm5y:`!j
sed '/^$/N;/\n$/D'      #方法2,允许顶部保留一空行,尾部不留空行BSD爱好者乐园,Wo2[4]A&t:UU
awk '{if(!match($0,/^$/)){print;F=1}else{if(F)print;F=0}}'  #同上面的方法2
k)^GB*h uOY!f!h# 只保留多个相邻空行的前两行。

'v!t4}P`BSD爱好者乐园 G3J5}.xc

sed '/^$/N;/\n$/N;//D'BSD爱好者乐园9B`m+N4yN8lH8A{
awk '{if(!match($0,/^$/)){print;F=0}else{if(F<2)print;F++}}'
KPRlH8cd me# 删除文件顶部的所有空行BSD爱好者乐园 gR @qhT/S*z

BSD爱好者乐园W'Sr_*ID`2a7^c S

sed '/./,$!d'
@7J;xu+{*E|Aawk '{if(F || !match($0,/^$/)){print;F=1}}'BSD爱好者乐园#E{'G/XVu-N@'E
# 删除文件尾部的所有空行

oAUc^,|Mz#t E.SBSD爱好者乐园 R @0Col1`;P

sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'  # 对所有sed有效
}$a%AyLpfsed -e :a -e '/^\n*$/N;/\n$/ba'        # 同上,但只对 gsed 3.02.*有效BSD爱好者乐园QdyX5t4J [2v
awk '/^.+$/{for(i=l;i<NR-1;i++)print "";print;l=NR}'
-J\ l(F;RHy}c# 删除每个段落的最后一行BSD爱好者乐园p-S'J dN"F$|

p\hNM5V dsed -n '/^$/{p;h;};/./{x;/./p;}'BSD爱好者乐园 ij-b:d dCs$L o
#很长,很ugly,应该有更好的办法

#y idv*?}BSD爱好者乐园N6{k%s$b Tpz F

awk -vRS= '{B=$0;l=0;f=1;while(match(B,/\n/)>0){print substr(B,l,RSTART-l-f);l=RSTART;sub(/\n/,"",B);f=0};print ""}'
+YS/Z@jQP1v8?特殊应用:BSD爱好者乐园BL.e%~+M)T(FG

BSD爱好者乐园 XNb g0H ?6[0?

# 移除手册页(man page)中的nroff标记。在Unix System V或bash shell下使
8p3P D6o p!x-T5X/U"?# 用’echo’命令时可能需要加上 -e 选项。BSD爱好者乐园.TRd-i j:}k

BSD爱好者乐园B6g.mcg#_+X

sed "s/.`echo\\\b`//g"    # 外层的双括号是必须的(Unix环境)BSD爱好者乐园1Y#CV7}:\
sed 's/.^H//g'             # 在bash或tcsh中, 按 Ctrl-V 再按 Ctrl-H
3xV S7|)N)S.LG+U xsed 's/.\x08//g'           # sed 1.5,GNU sed,ssed所使用的十六进制的表示方法BSD爱好者乐园&j k Y1k%N
awk '{gsub(/.\x08/,"",$0);print}'BSD爱好者乐园*v W#x`#q%z b4Y
# 提取新闻组或 e-mail 的邮件头

C-O.kQ q!uad3U

@fjA [sed '/^$/q'                # 删除第一行空行后的所有内容BSD爱好者乐园&xt(A]'Y
awk '{print}/^$/{exit}'
h`|@g# 提取新闻组或 e-mail 的正文部分BSD爱好者乐园/iQ!Yi ~ t-EE YB

BSD爱好者乐园'l wo$P'D@7s

sed '1,/^$/d'              # 删除第一行空行之前的所有内容
2q|-Bt6Ub#ri Zawk '{if(F)print}/^$/{F=1}'
&xn RNX3z6I+r&T# 从邮件头提取“Subject”(标题栏字段),并移除开头的“Subject:”字样

Rp C,{,@

f0w1kn nRsed '/^Subject: */!d; s///;q'
Xp}E5u iqr?awk '/^Subject:.*/{print substr($0,10)}/^$/{exit}'
b6T"oA.h;^# 从邮件头获得回复地址

MF*[8D6{9F-Ii!vHqABSD爱好者乐园O-eG(G!`;WeWW"G8pHN

sed '/^Reply-To:/q; /^From:/h; /./d;g;q'
"E4vSo(xj9bWAm4Aj#好像是输出第一个Reply-To:开头的行?From是干啥用的?不清楚规则。。

(@1DhGIBSD爱好者乐园'bDB"_oc

awk '/^Reply-To:.*/{print;exit}/^$/{exit}'
9}:y%YR:K,DH# 获取邮件地址。在上一个脚本所产生的那一行邮件头的基础上进一步的将非电邮地址的部分剃除。(见上一脚本)BSD爱好者乐园)C2\,FN/Na ].\

VfNB'?7uFsed 's/ *(.*)//; s/>.*//; s/.*[:<] *//'
~+u7SE$hz+~mU7A#取尖括号里的东西吧?BSD爱好者乐园eo~ E~I6x+|(H G!s4H

B)cjty7_*wawk -F'[<>]+' '{print $2}'BSD爱好者乐园'_"dz:h6rnn7y@
# 在每一行开头加上一个尖括号和空格(引用信息)BSD爱好者乐园 ~z t ^xl]

BSD爱好者乐园Q`I7bl|i

sed 's/^/> /'
;u.VY8V"| tawk '{print "> " $0}'
a'c'o"EX+J-qG# 将每一行开头处的尖括号和空格删除(解除引用)BSD爱好者乐园,z$Y&xOjY$kfkR

G\Q*F)T1M?sed 's/^> //'
Ow Y'QNP0~ zzawk '/^> /{print substr($0,3)}'BSD爱好者乐园Eb)d*| `3|h
# 移除大部分的HTML标签(包括跨行标签)BSD爱好者乐园N4]E KL|%Tda

B*WW5ZiMsed -e :a -e 's/<[^>]*>//g;/</N;//ba'BSD爱好者乐园+d3Q/HUd2Ra
awk '{gsub(/<[^>]*>/,"",$0);print}'BSD爱好者乐园.nSH&_D#@ X2B
# 将分成多卷的uuencode文件解码。移除文件头信息,只保留uuencode编码部分。
xq7b7K es!c/S# 文件必须以特定顺序传给sed。下面第一种版本的脚本可以直接在命令行下输入;BSD爱好者乐园1bpqpe0iD8u
# 第二种版本则可以放入一个带执行权限的shell脚本中。(由Rahul Dhesi的一
q G5B,^%av9h# 个脚本修改而来。)

hUDHD:P2rZX"JBSD爱好者乐园Fo\9bq{d#M

sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode   # vers. 1
]$oX-w^sed '/^end/,/^begin/d' "$@" | uudecode                    # vers. 2
9tLq9p-O|.r#我不想装个uudecode验证,大致写个吧

&rS+o"JX1Y zBSD爱好者乐园,c/[B v hhiQ

awk '/^end/{F=0}{if(F)print}/^begin/{F=1}' file1 file2 ... fileX
1U4Bq P,faU# 将文件中的段落以字母顺序排序。段落间以(一行或多行)空行分隔。GNU sed使用BSD爱好者乐园E q)Zp7XW2I/c$A8Q
# 字元“\v”来表示垂直制表符,这里用它来作为换行符的占位符——当然你也可以
vc2Zg&]6N# 用其他未在文件中使用的字符来代替它。BSD爱好者乐园,sRLMlBdfW

~.Jcc6u"W~sed '/./{H;d;};x;s/\n/={NL}=/g' file | sort | sed '1s/={NL}=//;s/={NL}=/\n/g'BSD爱好者乐园@}-jJ%t,~,qy
gsed '/./{H;d};x;y/\n/\v/' file | sort | sed '1s/\v//;y/\v/\n/'
!`b5jK0LN.kEaXawk -vRS= '{gsub(/\n/,"\v",$0);print}' ll.txt | sort | awk '{gsub(/\v/,"\n",$0);print;print ""}'BSD爱好者乐园-Uqf9v J+c Q*^
# 分别压缩每个.TXT文件,压缩后删除原来的文件并将压缩后的.ZIP文件
8wc-G SL#Z*}z o# 命名为与原来相同的名字(只是扩展名不同)。(DOS环境:“dir /b”
]8x,K vj:x5Bu# 显示不带路径的文件名)。

b0?q4GP:ky

aX'p&@$iYecho @echo off >zipup.batBSD爱好者乐园"Vgfe9]3s
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat
;G _M R6f%ChDOS 环境再次略过,而且我觉得这里用 bash 的参数 ${i%.TXT}.zip 替换更帅。BSD爱好者乐园LwQ&E\ w4c

;rmll,T g下面的一些 SED 说明略过,需要的朋友自行查看原文。

Xp2K$?wBSD爱好者乐园-u'X$F3if

{ Source. Thanks bones7456. }

$Z$i+B%e1K)c'N:P#d
[版权声明]BSD爱好者乐园站内文章,如来源不是互联网,则均系原创或翻译之作,可随意转载,或以此为基础进行演译,但务必以链接形式注明原始出处和作者信息,否则属于侵权行为。另对本站转载他处文章,俱有说明,如有侵权请联系本人,本人将会在第一时间删除侵权文章。
TAG: awk sed
 

评分:0

我来说两句

seccode