前幾天在CSDN上看到一個帖子
http://bbs.csdn.net/topics/390848841
,樓主貼了下面的問題:
例:123456789012345678901234567890如何能把上面數據轉換成123456789012345678901234567890
看了幾位網友的回覆,以爲仍是挺有意思,也收穫了一些知識,由於部分網友只給出瞭解決方法,沒有解釋下,我根據本身的理解,對幾個答案解釋下(不必定準確,錯誤之處請指正)
我認爲錯的答案
1 首先樓主給出了一個他說調試不出來的答案:
?!應該是非pattern結尾的意思,這個答案應該是說把非90結尾的行的換行符換位空。
這個答案應該是不可行的。sed默認單行模式,一次處理一行,運行時發現,就算咱們把換行符去掉了,sed命令結束後,仍是將它當成完整的一行輸出(也就是說,應該是自動又加上換行符了)
2. 有一位網友,以爲其餘答案太複雜,給出了下面的方法
這個答案使用了sed的多行模式,但應該是沒法實現樓主的目的的。咱們看運行結果「
windeal@ubuntu:~/Windeal/shell$ sed 'N;s/\n//g' a.txt
1234567890
1234567890123
4567890
能夠看出,sed 的N命令把第二行接到第一行後面,把第四行接到第三行後面,沒有考慮到咱們目標中:只有非90結尾的才把下一行附加上來。因此第四行的123被附加到第三行1234567890而出現了錯誤的結果。
我認爲對的答案
再來看兩個我認爲對的答案:
1.
sed -e '/^/{:loop /90$/!{N;b loop};s/\n//g}' test.txt > t2.txt
改一下好理解一點就是
sed '{:myloop /90$/!{N;b myloop};s/\n//g}' a.txt
/^/的意思我沒弄明白,應該是匹配每一行吧
在該命令中,myloop是一個自定義的標籤。相似程序語言中goto用的標籤。 N表示多行模式,b表示分支(至關於goto)
這樣就好理解了,sed會讀取一行內容,若是這一行不是以90結尾,/90$/! 就爲真,進入
{N;b myloop}。N就進入了多行模式,把下一行附加上來,而後進入分支b myloop,在判斷是否是以90結尾,這樣反覆讀取,直到讀到以90結尾的行。接下來模式空間的讀取工做已經完成,進入下一個命令,替換,
s/\n//g這個命令把當前模式空間的換行符都轉換爲空,也就是拼接成一行。
如此,咱們就完成了咱們要的目的。
2.
awk '{if($0~/90$/){print}else{printf("%s",$0)}}' a.txt
這個答案讀取了一行的因此字段(實際上就1個字段,) 用$0表示,而後
if($0~/90$/)判斷是否是以90結尾。
若是以90結尾,就輸出當前行數據。
若是不是,就格式化輸入當前航的字符串
注意print和printf的區別