-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsed.txt
executable file
·2049 lines (1681 loc) · 81.6 KB
/
sed.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1. sed -n ':a;1,5!{P;N;D;};N;ba' file
2. [解析]
这是删除文件末尾5行,原理是把第1到5行读入pattern space中,当读到第5行,超过了1,5的范畴后会执行花括号里的语句,就打印模式空间的第1行,然后再读取下一行内容,删除模式空间的第一行,并跳转到命令行首继续执行。这样就相当于隔5行打印前面的内容,最后的5行无法打印。
-n 使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN的数据一般都会被列出到屏幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来
-f :直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
-i :直接修改读取的档案内容,而不是由屏幕输出。
n1, n2 :不见得会存在,一般代表『选择进行动作的行数』
➜ shell cat a.sh|sed 's/macOS/徐乐/g;s/macos/xule/g'
<dict>
<key>phrase</key>
<string>徐乐</string>
<key>shortcut</key>
<string>xule</string>
</dict>
2个条件替换的话可以用;号来确认 [sed复合条件
egrep -i -n "cycle|capacity" -A 1 log-aggregated-2021-01-21-080141.ips|sed 's/<integer>//g;s/<\/integer>//g;s/<key>//g;s/<\/key>//g']
centos7 root@parallels:~# cat a.sh
<dict>
<key>phrase</key>
<string>macOS</string>
<key>shortcut</key>
<string>macos</string>
</dict>
centos7 root@parallels:~# cat a.sh |sed 's/macOS/徐乐/g;s/macos/xule/g'
<dict>
<key>phrase</key>
<string>徐乐</string>
<key>shortcut</key>
<string>xule</string>
</dict>
sed在macOS 下常见的一个报错
$ /Users/lex sudo su -
Mac:~ root# sed -i 's/216.58.215.229/108.177.97.109/g' /etc/hosts
sed: 1: "/etc/hosts": extra characters at the end of h command
Mac:~ root# sed -i "s/216.58.215.229/108.177.97.109/g" /etc/hosts
sed: 1: "/etc/hosts": extra characters at the end of h command
Mac:~ root# sed -i "" "s/216.58.215.229/108.177.97.109/g" /etc/hosts
sed '/cdef/r add.txt' input.txt
input.txt:
abcd
accd
cdef
line
web
add.txt:
line1
line2
line3
line4
Test:
sat:~# sed '/cdef/r add.txt' input.
txt
abcd
accd
cdef
line1
line2
line3
line4
line
web
If you want to apply the changes in input.txt file. Then, use -i with sed.
sed -i '/cdef/r add.txt' input.txt
If you want to use a regex as an expression you have to use the -E tag with sed.
sed -E '/RegexPattern/r add.txt' input.txt
仅作示例,只保留倒数 2、5 行:
sed -i -n "1{N;N;N;};N;${s/\n[^\n]*$//;s/[^\n]*\n//3;s/[^\n]*\n//2;p};D;" a.txt
awk /./ filename 删除文件的空行
删除段上几行下几行
$ cat text.txt
Hello New Wolrd.
Good day
host pc1{
Mac address: abc
IP address: qwe
User name: zxc
}
$
查找"Mac address: abc",然后删除从前面一行(host pc1{)到之后三行(})的内容。
操作后文件变成这样:
$ cat text.txt
Hello New Wolrd.
Good day
$
如何用脚本实现这样的操作?sed,awk,vim都可以。
sed '/Mac address/,+3d;:go;1!{P;$!N;D};N;bgo' file
sed '/Mac address/,+3d;:go;1,3!{P;$!N;D};N;bgo' file删除前3后3
<收起
下一行,前4行
sed '/check_nrpe\!check_ipsource/,+1d;:go;1,4!{P;$!N;D};N;bgo' linux27_27.cfg
open(File,"test.txt") || die "can't open this file \n"; my $str; while(<File>) { $str.="$_"; } close File; $str=~s/define[^\!]*\!check_ipsource[^define]*//gm; print $str;
这个是删除从define开始到下一个define,中间有!check_ipsource的
===================
sed更完內容自動備份
給未來的裕翔
如果想要對檔案內容的某個字
做一致的更換除了真的進去vim之外
可以考慮用sed
sed -i.bak 's/aaa/AAA/' targetFile
這樣就可以把targetFile裡面的aaa都換成AAA
-i.bak的意思是
換成AAA之後的檔案, 依然叫targetFile
但是換之前的, 存成targetFile.bak當備份
注意, -i和.bak中間不能有空白
而那個's/aaa/AAA/'的最後一個/不能省略
下面这个涉及到sed调用变量的问题
lxu@lxu-laptop:~$ cat /home/lxu/abc.txt
2011
lxu@lxu-laptop:~$ cat abc.sh
#!bin/sh
var1=`cat /home/lxu/abc.txt | bc`
var2=`expr $var1 + 1 | bc`
echo the final oldresult is $var1
echo the final newresult is $var2
sed -i "s/$var1/$var2/g" /home/lxu/abc.txt #sed要用双引号,awk变量顺序单双$var双单
lxu@lxu-laptop:~$ sh abc.sh
the final oldresult is 2011
the final newresult is 2012
lxu@lxu-laptop:~$ sh abc.sh
the final oldresult is 2012
the final newresult is 2013
对1072到1092行前面加#号
[root@B2G2BC conf]# sed -i '1074,1092s/^/#/' httpd.conf
清理所有HTML标签 sed 's/<[^>]*>//g'
是清理所有空格sed 's/[[:space:]]//g'
lxu@lxu-laptop:~/weather$ cat weather.html|sed 's/<[^>]*>//g'|sed 's/[[:space:]]//g'|sed '/^$/d'
lxu@lxu-laptop:~/weather$ cat weather.html|sed 's/<[^>]*>//g;s/[[:space:]]//g;/^$/d'
lxu@lxu-laptop:~/weather$ cat weather.html|sed '$!H;$!d;$G;$s/<[^>]*>//g'|sed 's/[[:space:]]//g'|sed '/^$/d'
把所有行都放到pattern space里面后就可以直接清除跨行标签了。比较正确的方法应该是这样:
'$!H;$!d;$G;$s/<[^>]*>//g'
文本间隔:
--------
http://sed.sourceforge.net/sed1line_zh-CN.html
# 在每一行后面增加一空行
sed G
# 将原来的所有空行删除并在每一行后面增加一空行。
# 这样在输出的文本中每一行后面将有且只有一空行。
sed '/^$/d;G'
# 在每一行后面增加两行空行
sed 'G;G'
# 将第一个脚本所产生的所有空行删除(即删除所有偶数行)
sed 'n;d'
打印偶数行奇书行
lxu@lxu-laptop:/home/date$ sed -n 'p;n' hosts奇书
192.168.2.100
192.168.2.101
192.168.2.102
192.168.2.103
192.168.2.104
lxu@lxu-laptop:/home/date$ sed -n 'n;p' hosts 偶数
sushi
liqingzhao
wanganshi
liyu
lijing
lxu@lxu-laptop:/home/date$ sed -n '1~2p' hosts
192.168.2.100
192.168.2.101
192.168.2.102
192.168.2.103
192.168.2.104
lxu@lxu-laptop:/home/date$ sed -n '2~2p' hosts
sushi
liqingzhao
wanganshi
liyu
lijing
# 在匹配式样“regex”的行之前插入一空行
sed '/regex/{x;p;x;}'
# 在匹配式样“regex”的行之后插入一空行
sed '/regex/G'
# 在匹配式样“regex”的行之前和之后各插入一空行
sed '/regex/{x;p;x;G;}'
在匹配式样“regex”的行之后增加2空行
sed '/regex/a\\'
sed '/regex/{G;G;}'
sed '/regex/G;/regex/G'
awk '/regex/{print $0"\n\n";next}1'
在空行后在增加一个空行
sed '/^$/G'
编号:
--------
在第一行之后追加
1a\
在行末$追加
$a\
#sed -i '$a\sudo sed -i "$a\/usr/local/sbin/puppetd --server songzhiwen" /etc/rc.d/rc.local' puppet.sh
在匹配的行ErrorLog之后追加一个test
sed -i '/ErrorLog/a\test'
在有5666的行之后追加一行
sed -i '/5666/a\-A INPUT -s 59.151.95.150 -m tcp -p tcp --dport 5666 -j ACCEPT' /etc/sysconfig/iptables
sed -i '/5666/a\-A INPUT -s 42.62.115.11 -m tcp -p tcp --dport 10050 -j ACCEPT' /etc/sysconfig/iptables
#!/bin/bash
sed -i '/7659/d' /etc/rc.d/firewall
sed -i '/5666/a\iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 7659 -j ACCEPT' /etc/rc.d/firewall
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 7659 -j ACCEPT
下面就是远程拷贝之后执行
pscp.pssh -h lv.txt iptables.sh /tmp
pssh -x '-t -t' -h lv.txt -l xule -t 800 -P "sudo /bin/bash /tmp/iptables.sh"
#/bin/bash
sed -i '/dport 5666/a\iptables -A INPUT -s 10.0.0.0/24 -p tcp --dport 5666 -j ACCEPT' /etc/rc.d/firewall
sed -i '/117.121.11.25 -p tcp --dport 22222/a\iptables -A INPUT -s 10.0.0.0/24 -p tcp --dport 22222 -j ACCEPT' /etc/rc.d/firewall
iptables -I INPUT -s 10.0.0.0/24 -p tcp --dport 5666 -j ACCEPT
iptables -I INPUT -s 10.0.0.0/24 -p tcp --dport 22222 -j ACCEPT
#/bin/bash
sed -i 's/117.121.11.25/117.121.11.25,42.62.25.133,10.0.0.186/' /usr/local/nagios/etc/nrpe.cfg
sed -i 's/117.121.11.25/117.121.11.25,42.62.25.133,10.0.0.186/' /etc/nagios/nrpe.cfg
sed -i '/dport 5666/a\iptables -A INPUT -s 10.0.0.0/24 -p tcp --dport 5666 -j ACCEPT' /etc/rc.d/firewall
sed -i '/117.121.11.25 -p tcp --dport 22222/a\iptables -A INPUT -s 10.0.0.0/24 -p tcp --dport 22222 -j ACCEPT' /etc/ rc.d/firewall
iptables -I INPUT -s 10.0.0.0/24 -p tcp --dport 5666 -j ACCEPT
iptables -I INPUT -s 10.0.0.0/24 -p tcp --dport 22222 -j ACCEPT
#/bin/bash
sed -i '/10.0.0.0/24 -p tcp --dport 5666 -j ACCEPT/a\iptables -A INPUT -s 42.62.25.133 -p tcp --dport 5666 -j ACCEPT' /etc/rc.d/firewall
iptables -I INPUT -s 42.62.25.133 -p tcp --dport 5666 -j ACCEPT
sed -i 's/117.121.11.25/117.121.11.25,42.62.25.133,10.0.0.186/' /usr/local/nagios/etc/nrpe.cfg
sed -i 's/117.121.11.25/117.121.11.25,42.62.25.133,10.0.0.186/' /etc/nagios/nrpe.cfg
kill -HUP `ps aux|grep nrpe.cfg|grep -v grep|awk '{print$2}'`
/etc/init.d/nrpe reload
sed "s/\(5666.*tcp\|tcp.*5666\).*/& \n test/g" firewall
查找文档b中同时包含one和three的行
b.txt的内容
one two three
four five six
one two
one seven three
gawk "/one/&&/three/" b.txt
sed -ne '/one/{/three/p}' b.txt
[jumpbox]➜ ~ cat b.txt
one two three
four five six
one two
one seven three
[jumpbox]➜ ~ sed -ne '/one/{/three/p}' b.txt
one two three
one seven three
[jumpbox]➜ ~ sed -n '/one/{/three/p}' b.txt
one two three
one seven three
[jumpbox]➜ ~ sed '/one.*three/!d' b.txt
one two three
one seven three
匹配2个条件
sed -n '/5666/{/tcp/p}' firewall
iptables -A INPUT -s 117.121.11.25 -p tcp --dport 5666 -j ACCEPT
sed -i '/5666/{/tcp/}a\ -A INPUT -s 59.109.32.160/28 -p tcp --dport 22222 -j ACCEPT' firewall
行内追加(即行内修改)如何做?实际是采用替换s /&
sed -i "s/all2:/&lxu,/" /etc/aliases
在all2:之后追加一个lxu,
行内追加的缺陷:如果用此法实现行尾追加,就必须把整个行不错一句的敲成pattern
all2:123,345
all2:lex,123,345
在匹配的行后面追加:,admin
|sed "/contact_groups/s/$/,admin/"
RewriteRule ^/youbian/s-(.*?)$ /?area=youbian&cmd=q&q=$1 [PT]
这个可以匹配sed -n '/RewriteRule ^\/youbian\/s/p'
for i in zhangji wanghan lulun gaoshi liqingzhao ;do ssh $i sed -n '658p' /usr/local/apache/conf/httpd.conf;done
RewriteRule ^/tuanqqpurse.php$ http://60.28.211.188/tuanqqpurse.php [L]
RewriteRule ^/tuanqqpurse.php$ http://60.28.211.188/tuanqqpurse.php [L]
RewriteRule ^/tuanqqpurse.php$ http://60.28.211.188/tuanqqpurse.php [L]
RewriteRule ^/tuanqqpurse.php$ http://60.28.211.188/tuanqqpurse.php [L]
RewriteRule ^/tuanqqpurse.php$ http://60.28.211.188/tuanqqpurse.php [L]
例如我在httpd.conf的657行之后增加RewriteRule ^/tuanqqpurse.php$ http://60.28.211.188/tuanqqpurse.php [L]
sed -i '657a\RewriteRule ^/tuanqqpurse.php$ http://60.28.211.188/tuanqqpurse.php [L]' httpd.conf
# 为文件中的每一行进行编号(简单的左对齐方式)。这里使用了“制表符”
# (tab,见本文末尾关于'\t'的用法的描述)而不是空格来对齐边缘。
sed = filename | sed 'N;s/\n/\t/'
# 对文件中的所有行编号(行号在左,文字右端对齐)。
sed = filename | sed 'N; s/^/ /; s/ *\(.\{6,\}\)\n/\1 /'
# 对文件中的所有行编号,但只显示非空白行的行号。
sed '/./=' filename | sed '/./N; s/\n/ /'
# 计算行数 (模拟 "wc -l")
sed -n '$='
还有一个
sed '=' abc
结果如下:
lxu@lxu-laptop:~$ cat abc
abc 130 120 135
ddd 160 113 140
ddd 145 170 215
lxu@lxu-laptop:~$ sed '=' abc
1
abc 130 120 135
2
ddd 160 113 140
3
ddd 145 170 215
文本转换和替代:
--------
# Unix环境:转换DOS的新行符(CR/LF)为Unix格式。
sed 's/.$//' # 假设所有行以CR/LF结束
sed 's/^M$//' # 在bash/tcsh中,将按Ctrl-M改为按Ctrl-V
sed 's/\x0D$//' # ssed、gsed 3.02.80,及更高版本
# Unix环境:转换Unix的新行符(LF)为DOS格式。
sed "s/$/`echo -e \\\r`/" # 在ksh下所使用的命令
sed 's/$'"/`echo \\\r`/" # 在bash下所使用的命令
sed "s/$/`echo \\\r`/" # 在zsh下所使用的命令
sed 's/$/\r/' # gsed 3.02.80 及更高版本
# DOS环境:转换Unix新行符(LF)为DOS格式。
sed "s/$//" # 方法 1
sed -n p # 方法 2
# DOS环境:转换DOS新行符(CR/LF)为Unix格式。
# 下面的脚本只对UnxUtils sed 4.0.7 及更高版本有效。要识别UnxUtils版本的
# sed可以通过其特有的“--text”选项。你可以使用帮助选项(“--help”)看
# 其中有无一个“--text”项以此来判断所使用的是否是UnxUtils版本。其它DOS
# 版本的的sed则无法进行这一转换。但可以用“tr”来实现这一转换。
sed "s/\r//" infile >outfile # UnxUtils sed v4.0.7 或更高版本
tr -d \r <infile >outfile # GNU tr 1.22 或更高版本
# 将每一行前导的“空白字符”(空格,制表符)删除
# 使之左对齐
sed 's/^[ \t]*//' # 见本文末尾关于'\t'用法的描述
# 将每一行拖尾的“空白字符”(空格,制表符)删除
sed 's/[ \t]*$//' # 见本文末尾关于'\t'用法的描述
# 将每一行中的前导和拖尾的空白字符删除
sed 's/^[ \t]*//;s/[ \t]*$//'
# 在每一行开头处插入5个空格(使全文向右移动5个字符的位置)
sed -n 's/^/86/p'
sed 's/^/ /'
# 在每一行开头处插入数字86
sed 's/^/86/'
# 在每一非空行开头处插入数字86
sed 's/[^$]/86/'
# 以79个字符为宽度,将所有文本右对齐
sed -e :a -e 's/^.\{1,78\}$/ &/;ta' # 78个字符外加最后的一个空格
host文件如下
192.168.2.21 baijuyi
192.168.2.22 liuzongyuan
192.168.2.23 menghaoran
需要结果如下:
在前面加echo "192.168.2.21 baijuyi" >> /etc/hosts
sed 's/^/echo "/' hosts |sed 's/[ \t]*$/" >> \/etc\/hosts/'
echo "192.168.2.88 Nmail" >> /etc/hosts
echo "192.168.2.89 Omail" >> /etc/hosts
echo "192.168.2.90 Pmail" >> /etc/hosts
# 以79个字符为宽度,使所有文本居中。在方法1中,为了让文本居中每一行的前
# 头和后头都填充了空格。 在方法2中,在居中文本的过程中只在文本的前面填充
# 空格,并且最终这些空格将有一半会被删除。此外每一行的后头并未填充空格。
sed -e :a -e 's/^.\{1,77\}$/ & /;ta' # 方法1
sed -e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/\( *\)\1/\1/' # 方法2
# 在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”
sed 's/foo/bar/' # 只替换每一行中的第一个“foo”字串
sed 's/foo/bar/4' # 只替换每一行中的第四个“foo”字串
sed 's/foo/bar/g' # 将每一行中的所有“foo”都换成“bar”
sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # 替换倒数第二个“foo”
sed 's/\(.*\)foo/\1bar/' # 替换最后一个“foo”
匹配dport 25的行中前面加#
sed '/dport 25/s/-A/#-A/' iptables
# 只在行中出现字串“baz”的情况下将“foo”替换成“bar”
sed '/baz/s/foo/bar/g'
# 将“foo”替换成“bar”,并且只在行中未出现字串“baz”的情况下替换
sed '/baz/!s/foo/bar/g'
# 不管是“scarlet”“ruby”还是“puce”,一律换成“red”
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g' #对多数的sed都有效
gsed 's/scarlet\|ruby\|puce/red/g' # 只对GNU sed有效
# 倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)。
# 由于某些原因,使用下面命令时HHsed v1.5会将文件中的空行删除
sed '1!G;h;$!d' # 方法1
sed -n '1!G;h;$p' # 方法2
# 将行中的字符逆序排列,第一个字成为最后一字,……(模拟“rev”)
sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'
# 将每两行连接成一行(类似“paste”) 合并
sed '$!N;s/\n/ /'
sed 'N;s/\n//'
五行连接成一行
awk 'ORS=NR%5?" ":"\n"{print}'
# 如果当前行以反斜杠“\”结束,则将下一行并到当前行末尾
# 并去掉原来行尾的反斜杠
sed -e :a -e '/\\$/N; s/\\\n//; ta'
# 如果当前行以等号开头,将当前行并到上一行末尾
# 并以单个空格代替原来行头的“=”
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
# 为数字字串增加逗号分隔符号,将“1234567”改为“1,234,567”
gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta' # GNU sed
sed -e :a -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta' # 其他sed
# 为带有小数点和负号的数值增加逗号分隔符(GNU sed)
gsed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta'
# 在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)
gsed '0~5G' # 只对GNU sed有效
sed 'n;n;n;n;G;' # 其他sed
大括号作用于同一地址应用多个命令
sed '/Consult/{s/in/IN/;s/Owner/OWNER/}' abc
Consult Section 3.1 IN the OWNER and Operator
$ cat abc
Consult Section 3.1 in the Owner and Operator
选择性地显示特定行:
--------
# 显示文件中的前10行 (模拟“head”的行为)
sed 10q
# 显示文件中的第一行 (模拟“head -1”命令)
sed q
# 显示文件中的最后10行 (模拟“tail”)
sed -e :a -e '$q;N;11,$D;ba'
保留10行sed -i -e :a -e '$q;N;11,$D;ba' /tmp/b
# 显示文件中的最后2行(模拟“tail -2”命令)
sed '$!N;$!D'
# 显示文件中的最后一行(模拟“tail -1”)
sed '$!d' # 方法1
sed -n '$p' # 方法2
# 显示文件中的倒数第二行
sed -e '$!{h;d;}' -e x # 当文件中只有一行时,输入空行
sed -e '1{$q;}' -e '$!{h;d;}' -e x # 当文件中只有一行时,显示该行
sed -e '1{$d;}' -e '$!{h;d;}' -e x # 当文件中只有一行时,不输出
# 只显示匹配正则表达式的行(模拟“grep”)
sed -n '/regexp/p' # 方法1
sed '/regexp/!d' # 方法2
# 只显示“不”匹配正则表达式的行(模拟“grep -v”)
sed -n '/regexp/!p' # 方法1,与前面的命令相对应
sed '/regexp/d' # 方法2,类似的语法
举例如下:
有一个文本文件,大约是4亿行,每行都是
aaaaaaaaaa
bbbbbbbbbb
这样的10个字符,
但是其中有很少的不是10个字符的行(比如7个或者8个字符),想用脚本把这些行挑出来,
请问脚本应该怎么写?
sed '/........../d'
sed -n '/........../!p' 123
awk 'length($0)!=10'
grep -v '..........'
# 查找“regexp”并将匹配行的上一行显示出来,但并不显示匹配行
sed -n '/regexp/{g;1!p;};h'
# 查找“regexp”并将匹配行的下一行显示出来,但并不显示匹配行
sed -n '/regexp/{n;p;}'
# 显示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所
# 在行的行号 (类似“grep -A1 -B1”)
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
# 显示包含“AAA”、“BBB”或“CCC”的行(任意次序)
sed '/AAA/!d; /BBB/!d; /CCC/!d' # 字串的次序不影响结果
# 显示包含“AAA”、“BBB”和“CCC”的行(固定次序)
sed '/AAA.*BBB.*CCC/!d'
# 显示包含“AAA”“BBB”或“CCC”的行 (模拟“egrep”)
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d # 多数sed
gsed '/AAA\|BBB\|CCC/!d' # 对GNU sed有效
# 显示包含“AAA”的段落 (段落间以空行分隔)
# HHsed v1.5 必须在“x;”后加入“G;”,接下来的3个脚本都是这样
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'
显示包括Serial Number的段落
➜ ~ system_profiler SPPowerDataType|sed -e '/./{H;$!d;}' -e 'x;/Serial Number/!d;'
Model Information:
Serial Number: F5D81927C63J67V6T
Manufacturer: DSY
Device Name: bq20z451
Pack Lot Code: 0
PCB Lot Code: 0
Firmware Version: 901
Hardware Revision: 2
Cell Revision: 1734
Charge Information:
Charge Remaining (mAh): 6426
Fully Charged: Yes
Charging: No
Full Charge Capacity (mAh): 6578
Health Information:
Cycle Count: 32
Condition: Normal
Battery Installed: Yes
Amperage (mA): -4
Voltage (mV): 12630
Connected: Yes
ID: 0x1656
Wattage (W): 86
Family: 0xe000400a
Serial Number: C0464510C42GW85AM
Name: 87W USB-C Power Adapter
Manufacturer: Apple Inc.
Hardware Version: 1.0
Firmware Version: 1070068
Charging: No
# 显示包含“AAA”“BBB”和“CCC”三个字串的段落 (任意次序)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
# 显示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d' # 只对GNU sed有效
# 显示包含65个或以上字符的行
sed -n '/^.\{65\}/p'
# 显示包含65个以下字符的行
sed -n '/^.\{65\}/!p' # 方法1,与上面的脚本相对应
sed '/^.\{65\}/d' # 方法2,更简便一点的方法
# 显示部分文本——从包含正则表达式的行开始到最后一行结束
sed -n '/regexp/,$p'
# 从某关键字的行开始到最后一行删除掉
sed -n '/regexp/,$!p'
# 某关键字的下一行开始到最后一行删除掉
sed '1,/regexp/!d'
sed -n '1,/regexp/p'
# 显示部分文本——指定行号范围(从第8至第12行,含8和12行)
sed -n '8,12p' # 方法1
sed '8,12!d' # 方法2
# 显示第52行
sed -n '52p' # 方法1
sed '52!d' # 方法2
sed '52q;d' # 方法3, 处理大文件时更有效率
# 从第3行开始,每7行显示一次
gsed -n '3~7p' # 只对GNU sed有效
sed -n '3,${p;n;n;n;n;n;n;}' # 其他sed
# 显示两个正则表达式之间的文本(包含)
sed -n '/Iowa/,/Montana/p' # 区分大小写方式
system_profiler SPPowerDataType|sed -n '/AC Charger Information:/,/Power Events:/p'
system_profiler SPPowerDataType|sed -n "/AC Charger Information:/,/Power Events:/p"
打印范围2个条件:
➜ ~system_profiler SPPowerDataType|sed -n "/AC Charger Information:/,/Power Events:/p;/Health Information:/,/Battery Installed/p"
➜ ~ system_profiler SPPowerDataType|sed -n "/AC Charger Information:/,/Power Events:/p;/Health Information:/,/Voltage/p"
Health Information:
Cycle Count: 32
Condition: Normal
Battery Installed: Yes
Amperage (mA): -2
Voltage (mV): 12637
AC Charger Information:
Connected: Yes
ID: 0x1656
Wattage (W): 86
Family: 0xe000400a
Serial Number: C0464510C42GW85AM
Name: 87W USB-C Power Adapter
Manufacturer: Apple Inc.
Hardware Version: 1.0
Firmware Version: 1070068
Charging: No
Power Events:
system_profiler SPPowerDataType|sed -n '/AC Charger Information:/,/Power Events:/p'
AC Charger Information:
Connected: Yes
ID: 0x1656
Wattage (W): 86
Family: 0xe000400a
Serial Number: C0464510C42GW85AM
Name: 87W USB-C Power Adapter
Manufacturer: Apple Inc.
Hardware Version: 1.0
Firmware Version: 1070068
Charging: No
Power Events:
例如打印某段时间开始到某段时间结束
sed -n '/^Jun 6 04:05:11/,/^Jun 6 04:15:10/p' maillog
sed -n '834,837p' maillog
选择性地删除特定行:
--------
-n, --line-number print line number with output lines
grep -n "[email protected] " maillog 换个查出[email protected]的行
awk '/^root/,/^mysql/' test----打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记 录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾
# 显示通篇文档,除了两个正则表达式之间的内容
sed '/Iowa/,/Montana/d'
# 删除文件中相邻的重复行(模拟“uniq”)
# 只保留重复行中的第一行,其他行删除
sed '$!N; /^\(.*\)\n\1$/!P; D'
# 删除文件中的重复行,不管有无相邻。注意hold space所能支持的缓存
# 大小,或者使用GNU sed。
sed -n 'G; s/\n/&&/; /^\([ -~]*\n\).*\n\1/d; s/\n//; h; P'
# 删除除重复行外的所有行(模拟“uniq -d”)
sed '$!N; s/^\(.*\)\n\1$/\1/; t; D'
https://www.mkyong.com/mac/sed-command-hits-undefined-label-error-on-mac-os-x/
undefined label
# 删除文件中开头的10行
sed '1,10d'
#保留regexp之前的行
sed '1,/regexp/!d'
# 删除文件中的最后一行
sed '$d'
# 删除文件中的最后两行
sed 'N;$!P;$!D;$d'
# 删除文件中的最后10行
sed -e :a -e '$d;N;2,10ba' -e 'P;D' # 方法1
sed -n -e :a -e '1,10!{P;N;D;};N;ba' # 方法2
# 删除8的倍数行
gsed '0~8d' # 只对GNU sed有效
sed 'n;n;n;n;n;n;n;d;' # 其他sed
# 删除匹配式样的行
sed '/pattern/d' # 删除含pattern的行。当然pattern
# 可以换成任何有效的正则表达式
vi的时候是
3. 删除包含特定字符串的行
:g/pattern/d
# 删除文件中的所有空行(与“grep '.' ”效果相同)
sed '/^$/d' # 方法1
sed '/./!d' # 方法2
# 只保留多个相邻空行的第一行。并且删除文件顶部和尾部的空行。
# (模拟“cat -s”)
sed '/./,/^$/!d' #方法1,删除文件顶部的空行,允许尾部保留一空行
sed '/^$/N;/\n$/D' #方法2,允许顶部保留一空行,尾部不留空行
# 只保留多个相邻空行的前两行。
sed '/^$/N;/\n$/N;//D'
# 删除文件顶部的所有空行
sed '/./,$!d'
# 删除文件尾部的所有空行
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' # 对所有sed有效
sed -e :a -e '/^\n*$/N;/\n$/ba' # 同上,但只对 gsed 3.02.*有效
# 删除每个段落的最后一行
sed -n '/^$/{p;h;};/./{x;/./p;}'
删除200001行到行末
sed -i '2000001,$d' oupeng
剩余2000000 oupeng
#清空文件
sed -i '1,$d' file
特殊应用:
--------
# 移除手册页(man page)中的nroff标记。在Unix System V或bash shell下使
# 用'echo'命令时可能需要加上 -e 选项。
sed "s/.`echo \\\b`//g" # 外层的双括号是必须的(Unix环境)
sed 's/.^H//g' # 在bash或tcsh中, 按 Ctrl-V 再按 Ctrl-H
sed 's/.\x08//g' # sed 1.5,GNU sed,ssed所使用的十六进制的表示方法
# 提取新闻组或 e-mail 的邮件头
sed '/^$/q' # 删除第一行空行后的所有内容
# 提取新闻组或 e-mail 的正文部分
sed '1,/^$/d' # 删除第一行空行之前的所有内容
# 从邮件头提取“Subject”(标题栏字段),并移除开头的“Subject:”字样
sed '/^Subject: */!d; s///;q'
# 从邮件头获得回复地址
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'
# 获取邮件地址。在上一个脚本所产生的那一行邮件头的基础上进一步的将非电邮
# 地址的部分剃除。(见上一脚本)
sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//'
# 在每一行开头加上一个尖括号和空格(引用信息)
sed 's/^/> /'
# 将每一行开头处的尖括号和空格删除(解除引用)
sed 's/^> //'
# 移除大部分的HTML标签(包括跨行标签)
sed -e :a -e 's/<[^>]*>//g;/</N;//ba'
# 将分成多卷的uuencode文件解码。移除文件头信息,只保留uuencode编码部分。
# 文件必须以特定顺序传给sed。下面第一种版本的脚本可以直接在命令行下输入;
# 第二种版本则可以放入一个带执行权限的shell脚本中。(由Rahul Dhesi的一
# 个脚本修改而来。)
sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode # vers. 1
sed '/^end/,/^begin/d' "$@" | uudecode # vers. 2
# 将文件中的段落以字母顺序排序。段落间以(一行或多行)空行分隔。GNU sed使用
# 字元“\v”来表示垂直制表符,这里用它来作为换行符的占位符——当然你也可以
# 用其他未在文件中使用的字符来代替它。
sed '/./{H;d;};x;s/\n/={NL}=/g' file | sort | sed '1s/={NL}=//;s/={NL}=/\n/g'
gsed '/./{H;d};x;y/\n/\v/' file | sort | sed '1s/\v//;y/\v/\n/'
# 分别压缩每个.TXT文件,压缩后删除原来的文件并将压缩后的.ZIP文件
# 命名为与原来相同的名字(只是扩展名不同)。(DOS环境:“dir /b”
# 显示不带路径的文件名)。
echo @echo off >zipup.bat
dir /b *.txt | sed "s/^\(.*\)\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat
使用SED:Sed接受一个或多个编辑命令,并且每读入一行后就依次应用这些命令。
当读入第一行输入后,sed对其应用所有的命令,然后将结果输出。接着再读入第二
行输入,对其应用所有的命令……并重复这个过程。上一个例子中sed由标准输入设
备(即命令解释器,通常是以管道输入的形式)获得输入。在命令行给出一个或多
个文件名作为参数时,这些文件取代标准输入设备成为sed的输入。sed的输出将被
送到标准输出(显示器)。因此:
cat filename | sed '10q' # 使用管道输入
sed '10q' filename # 同样效果,但不使用管道输入
sed '10q' filename > newfile # 将输出转移(重定向)到磁盘上
要了解sed命令的使用说明,包括如何通过脚本文件(而非从命令行)来使用这些命
令,请参阅《sed & awk》第二版,作者Dale Dougherty和Arnold Robbins
(O'Reilly,1997;http://www.ora.com),《UNIX Text Processing》,作者
Dale Dougherty和Tim O'Reilly(Hayden Books,1987)或者是Mike Arst写的教
程——压缩包的名称是“U-SEDIT2.ZIP”(在许多站点上都找得到)。要发掘sed
的潜力,则必须对“正则表达式”有足够的理解。正则表达式的资料可以看
《Mastering Regular Expressions》作者Jeffrey Friedl(O'reilly 1997)。
Unix系统所提供的手册页(“man”)也会有所帮助(试一下这些命令
“man sed”、“man regexp”,或者看“man ed”中关于正则表达式的部分),但
手册提供的信息比较“抽象”——这也是它一直为人所诟病的。不过,它本来就不
是用来教初学者如何使用sed或正则表达式的教材,而只是为那些熟悉这些工具的人
提供的一些文本参考。
括号语法:前面的例子对sed命令基本上都使用单引号('...')而非双引号
("...")这是因为sed通常是在Unix平台上使用。单引号下,Unix的shell(命令
解释器)不会对美元符($)和后引号(`...`)进行解释和执行。而在双引号下
美元符会被展开为变量或参数的值,后引号中的命令被执行并以输出的结果代替
后引号中的内容。而在“csh”及其衍生的shell中使用感叹号(!)时需要在其前
面加上转义用的反斜杠(就像这样:\!)以保证上面所使用的例子能正常运行
(包括使用单引号的情况下)。DOS版本的Sed则一律使用双引号("...")而不是
引号来圈起命令。
'\t'的用法:为了使本文保持行文简洁,我们在脚本中使用'\t'来表示一个制表
符。但是现在大部分版本的sed还不能识别'\t'的简写方式,因此当在命令行中为
脚本输入制表符时,你应该直接按TAB键来输入制表符而不是输入'\t'。下列的工
具软件都支持'\t'做为一个正则表达式的字元来表示制表符:awk、perl、HHsed、
sedmod以及GNU sed v3.02.80。
不同版本的SED:不同的版本间的sed会有些不同之处,可以想象它们之间在语法上
会有差异。具体而言,它们中大部分不支持在编辑命令中间使用标签(:name)或分
支命令(b,t),除非是放在那些的末尾。这篇文档中我们尽量选用了可移植性较高
的语法,以使大多数版本的sed的用户都能使用这些脚本。不过GNU版本的sed允许使
用更简洁的语法。想像一下当读者看到一个很长的命令时的心情:
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
好消息是GNU sed能让命令更紧凑:
sed '/AAA/b;/BBB/b;/CCC/b;d' # 甚至可以写成
sed '/AAA\|BBB\|CCC/b;d'
此外,请注意虽然许多版本的sed接受象“/one/ s/RE1/RE2/”这种在's'前带有空
格的命令,但这些版本中有些却不接受这样的命令:“/one/! s/RE1/RE2/”。这时
只需要把中间的空格去掉就行了。
速度优化:当由于某种原因(比如输入文件较大、处理器或硬盘较慢等)需要提高
命令执行速度时,可以考虑在替换命令(“s/.../.../”)前面加上地址表达式来
提高速度。举例来说:
sed 's/foo/bar/g' filename # 标准替换命令
sed '/foo/ s/foo/bar/g' filename # 速度更快
sed '/foo/ s//bar/g' filename # 简写形式
当只需要显示文件的前面的部分或需要删除后面的内容时,可以在脚本中使用“q”
命令(退出命令)。在处理大的文件时,这会节省大量时间。因此:
sed -n '45,50p' filename # 显示第45到50行
sed -n '51q;45,50p' filename # 一样,但快得多
如果你有其他的单行脚本想与大家分享或者你发现了本文档中错误的地方,请发电
子邮件给本文档的作者(Eric Pement)。邮件中请记得提供你所使用的sed版本、
该sed所运行的操作系统及对问题的适当描述。本文所指的单行脚本指命令行的长
度在65个字符或65个以下的sed脚本〔译注1〕。本文档的各种脚本是由以下所列作
者所写或提供:
Al Aab # 建立了“seders”邮件列表
Edgar Allen # 许多方面
Yiorgos Adamopoulos # 许多方面
Dale Dougherty # 《sed & awk》作者
Carlos Duarte # 《do it with sed》作者
Eric Pement # 本文档的作者
Ken Pizzini # GNU sed v3.02 的作者
S.G. Ravenhall # 去html标签脚本
Greg Ubben # 有诸多贡献并提供了许多帮助
-------------------------------------------------------------------------
译注1:大部分情况下,sed脚本无论多长都能写成单行的形式(通过`-e'选项和`;'
号)——只要命令解释器支持,所以这里说的单行脚本除了能写成一行还对长度有
所限制。因为这些单行脚本的意义不在于它们是以单行的形式出现。而是让用户能
方便地在命令行中使用这些紧凑的脚本才是其意义所在。
去除掉test1中的空格
[root@mail ~]# cat test1
0 12 2r 4 t t
[root@mail ~]# awk '{for(i=1;i<=NF;i++)printf$i;printf"\n"}' test1
0122r4tt
[root@mail ~]# sed 's/\ //g' test1
0122r4tt
[root@mail ~]# sed 's/ //g' test1
0122r4tt
取前三个字符
lxu@lxu-laptop:~$ echo "abcddef"|sed 's/\(...\).*/\1/'
abc
lxu@lxu-laptop:~$ echo "abcddef"|sed 's/\(.\{3\}\).*/\1/'
abc
(...\).*
(.\{3\}\).*
lxu@lxu-laptop:~$ echo "abcddef"|cut -b1-3
abc
长选项必须使用的参数对于短选项时也是必需使用的。
-b, --bytes=列表 只选中指定的这些字节
取后三个字符
lxu@lxu-laptop:~$ echo "ABCDEF"|sed 's/.*\(...\)$/\1/'
DEF
sed编辑器使用圆括号定义替换模式中的子字符串元素,然后在替换模式中使用特定的符号来引用字符串元素,
替换字符由反斜杠和数字组成,数字表示字符串元素的位置,
sed编辑器将第一个元素分配为字符\1
第二个元素分配为字符\2
The System Administrator manual
用User替换Administrator
lxu@lxu-laptop:~$ echo "The System Administrator manual"|sed 's/\(System\) Administrator/\1 User/'
The System User manual
lxu@lxu-laptop:~$ echo "The System Administrator manual"|sed 's/Administrator/User/g'
The System User manual
下面这个好理解些 对于文件中有 furry hat将furry hat中的hat替换为cat
lxu@lxu-laptop:~$ cat def
That furry hat is pretty
That furry hat is tow
hello
That furrt hat is pretty
That furry hac is pretty
lxu@lxu-laptop:~$ cat def |sed 's/\(furry\) hat/\1 cat/'
That furry cat is pretty
That furry cat is tow
hello
That furrt hat is pretty
That furry hac is pretty
继续举例如下:
lxu@lxu-laptop:~$ cat for.sh
for i in 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18
do
echo $i
done
将for用\1调用替换 那么原文件是不变的
lxu@lxu-laptop:~$ sed "s/\(for\)/\1/g" for.sh
for i in 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18
do
echo $i
done
将for用FOR替换
lxu@lxu-laptop:~$ sed "s/\(for\)/FOR/g" for.sh
FOR i in 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18
do
echo $i
done
Time Functions
Since one of the primary uses of AWK programs is processing log files that contain time stamp
information, gawk provides the following functions for obtaining time stamps and formatting
them.
mktime(datespec)
Turns datespec into a time stamp of the same form as returned by systime(). The date-
spec is a string of the form YYYY MM DD HH MM SS[ DST]. The contents of the string
are six or seven numbers representing respectively the full year including century,
the month from 1 to 12, the day of the month from 1 to 31, the hour of the day from 0
to 23, the minute from 0 to 59, and the second from 0 to 60, and an optional daylight
saving flag. The values of these numbers need not be within the ranges specified; for
example, an hour of -1 means 1 hour before midnight. The origin-zero Gregorian calen-
dar is assumed, with year 0 preceding year 1 and year -1 preceding year 0. The time
is assumed to be in the local timezone. If the daylight saving flag is positive, the
time is assumed to be daylight saving time; if zero, the time is assumed to be stan-
dard time; and if negative (the default), mktime() attempts to determine whether day-
light saving time is in effect for the specified time. If datespec does not contain
enough elements or if the resulting time is out of range, mktime() returns -1.
strftime([format [, timestamp[, utc-flag]]])
Formats timestamp according to the specification in format. If utc-flag is present
and is non-zero or non-null, the result is in UTC, otherwise the result is in local
time. The timestamp should be of the same form as returned by systime(). If times-
tamp is missing, the current time of day is used. If format is missing, a default
format equivalent to the output of date(1) is used. See the specification for the
strftime() function in ANSI C for the format conversions that are guaranteed to be
available.
systime() Returns the current time of day as the number of seconds since the Epoch (1970-01-01
00:00:00 UTC on POSIX systems).