例:
12345
67890
1234567890
123
4567890
如何能把上面數據轉換成
1234567890
1234567890
1234567890
看了幾位網友的回復,覺得還是挺有意思,也收獲了一些知識,因為部分網友只給出了解決方法,沒有解釋下,我根據自己的理解,對幾個答案解釋下(不一定准確,錯誤之處請指正)
我認為錯的答案
1 首先樓主給出了一個他說調試不出來的答案:
sed 's/(?!90)\n//g'
?!應該是非pattern結尾的意思,這個答案應該是說把非90結尾的行的換行符換位空。
這個答案應該是不可行的。sed默認單行模式,一次處理一行,運行時發現,就算我們把換行符去掉了,sed命令結束后,還是將它當成完整的一行輸出(也就是說,應該是自動又加上換行符了)
2. 有一位網友,覺得其他答案太復雜,給出了下面的方法
sed ‘N;s/\n//g’
這個答案使用了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的區別