sed行處理詳解(交換行,合並行,刪除行等)


1.合並行

zj@zj:~/Script/blog_script$ cat test1
1
2
3
4
合並上下兩行
zj@zj:~/Script/blog_script$ sed '$!N;s/\n/\t/' test1
1    2
3    4
合並匹配模式及其下一行
zj@zj:~/Script/blog_script$ sed '/2/{N;s/\n/\t/}' test1
1
2    3
4
合並所有行
zj@zj:~/Script/blog_script$ sed ':a;N;s/\n/\t/;ba;' test1
1    2    3    4

2.交換行
2.1已知行號時交換兩行
zj@zj:~/Script/blog_script$ cat test
baidu music so terrible so bad
microsoft haha haha
yahoo byebye
google princess so good
這里是交換1,4行.當然你可以根據自己需要修改
zj@zj:~/Script/blog_script$ for(( i=1;i<=4;i++ )); do  case $i in 1) sed -n 4p test;; 4) sed -n 1p test;; *) sed -n ${i}p test;; esac; done
google princess so good
microsoft haha haha
yahoo byebye
baidu music so terrible so bad
連續時好說:
zj@zj:~/Script/blog_script$ sed '1{h;d};2{G}' test
microsoft haha haha
baidu music so terrible so bad
yahoo byebye
google princess so good

2.2不知道行號
要交換的兩行是連續行的情況下:
zj@zj:~/Script/blog_script$ sed '/baidu/{h;d};/microsoft/{G}' test
microsoft haha haha
baidu music so terrible so bad
yahoo byebye
google princess so good
ps:交換包含bai與microsoft的行
兩行不連續的情況:

zj@zj:~/Script/blog_script$ sed '/baidu/{:a;N;/google/!ba;s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' test
google princess so good
microsoft haha haha
yahoo byebye
baidu music so terrible so bad
ps:交換含有baidu與google的行

研究了下寫了個不論連續不連續的都可以的:
zj@zj:~/Script/blog_script$ sed '/baidu/{:a;N;/microsoft/!ba;/[^\n]*baidu[^\n]*\n[^\n]*microsoft[^\n]*$/{s/\([^\n]*baidu[^\n]*\)\n\(.*\)/\2\n\1/};s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' test
microsoft haha haha
baidu music so terrible so bad
yahoo byebye
google princess so good

zj@zj:~/Script/blog_script$ sed '/baidu/{:a;N;/google/!ba;/[^\n]*baidu[^\n]*\n[^\n]*google[^\n]*$/{s/\([^\n]*baidu[^\n]*\)\n\(.*\)/\2\n\1/;};s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' test
google princess so good
microsoft haha haha
yahoo byebye
baidu music so terrible so bad

ps:上面代碼
/baidu/{....}  遇到含有baidu的行,開始做{}中的命令序列
:a;N;/google/!ba  循環讀信息,直到讀取google.
/[^\n]*baidu[^\n]*\n[^\n]*google[^\n]*$/這個就是說如果哦baidu與google之間只有一個\n,即這兩個是連續行就:{s/\([^\n]*baidu[^\n]*\)\n\(.*\)/\2\n\1/;}交換這兩行

如果不匹配上面的模式就是說不是連續行了.
s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}
而在匹配連續行的情況下是不可能匹配上面表達式的.ok~~~~

3.忘了還有交互奇偶行
zj@zj:~/Script/blog_script$ sed '$!N;s/\([^\n]*\)\n\([^\n]*\)/\2\n\1/' test
microsoft haha haha
baidu music so terrible so bad
google princess so good
yahoo byebye

4.刪除行就不用說了吧
d嘍....

5.刪除空行
sed '/^$/d' test2
刪除多個空行為一個空行
sed '/^$/{N;/^\n*$/D}' test2
 
轉載自:http://blog.chinaunix.net/uid-9950859-id-98222.html
 

附:sed的合並行的方法

處理前:
114.113.144.2:
19ms
19ms
19ms
36ms
22ms
19ms
18ms
218.61.204.73:
0ms
0ms
0ms
0ms
0ms
0ms
0ms
處理后:
114.113.144.2: 19ms 19ms 19ms 36ms 22ms 19ms 18ms
218.61.204.73: 0ms 0ms 0ms 0ms 0ms 0ms 0ms
 
解決方法(稍有改動):
1. awk 'NR>1&&!/ms/{print ""}{printf $0" "}END{print ""}' file
解釋:行號大於1且沒有匹配到ms就換行,把每一行都打印出來,用空格隔開,最后,換行。
 
2. sed ':a;$!N;/ms$/s/\n/ /;ta;P;D' file
解釋:設置一個標簽a,除了最后一行,其他行都執行把下一行的數據添加到模式空間,當匹配到以ms結尾的行就把換行符換成空格,如果替換成功,就重復執行a否則就將模式空間的第一行打印出來,然后刪除模式空間的第一行,開始下一個循環。
重點解釋一下P和D:
P:打印模式空間的第一行。
D:刪除模式空間的第一行,開始一個新的循環。
這個命令第一次打印前的模式空間的內容是:
114.113.144.2: 19ms 19ms 19ms 36ms 22ms 19ms 18ms
218.61.204.73:
通過P命令,sed就會把第一行打印出來,然后再通過D命令,把第一行刪掉,然后第二行就變成第一行了。此時模式空間的內容就是:
218.61.204.73:
 
3. cat file | xargs -n8
 
4. paste -sd '       \n' file
-s:將一個文件的數據每次都水平地輸出。
-d '       \n':將默認分隔符Tab換成7個空格和1個換行符,即前8個數據用空格隔開,然后換行。
 
5. sed -e :a -e '$!N;/\n.*ms/{s/\n/ /;ta};P;D' file
解釋:我不知道寫這命令的人為什么要用-e,其實直接用 sed ':a;$!N;/\n.*ms/s/\n/ /;ta;P;D' file不是更好?這個命令跟第2個命令是一樣。
 
6. sed -n '/^.*[.]/{:m;N;/\n.*[.]/!{s/\n/ /;bm};P} file
解釋:這個命令的運行結果是:
114.113.144.2: 19ms 19ms 19ms 36ms 22ms 19ms 18ms
只有一行,所以肯定有問題,經我改過之后是這樣的:sed '/^.*[.]/{:m;N;/\n.*[.]/!{s/\n/ /;bm};P;D} file,方法跟第2個命令是一樣的,只是把簡單問題復雜化了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM