2012-06-08 176 views
2

我有一個如下所示的文本文件。它有一些額外的換行符,我想刪除。使用shell腳本刪除換行符

LINE1: @Line1Col1 @Line1Col2 

LINE2: @Line1Col3 @Line1Col4 @ [email protected] 

LINE3: @Line2Col1 @Line2Col2 @Line2Col3 

LINE4: @[email protected] 

LINE5: Line2Col5 @ 

我想刪除換行符,這樣它看起來是這樣的:如果它與@頭開始,以@符結束

@Line1Col1 @Line1Col2 @Line1Col3 @Line1Col4 @[email protected] 

@Line2Col1 @Line2Col2 @Line2Col3 @[email protected] [email protected] 

的線被定義爲完整的。 請注意,分隔符@已經存在於文件中。 例如,追加LINE1和LINE2使該行完整。 類似地,追加LINE3,LINE4和LINE5會形成另一個完整的行(其中,每行上的數據LineXcolX用於說明目的)。 所以,我需要刪除LINE1中的換行符,並在LINE2中保留換行符。 同樣,我需要刪除LINE3和LINE4中的換行符,並在LINE5中保留換行符。 中間可以有多個空格;因此,空間不能用於解決方案。

重新編輯[增加了一個實際文件的部分]

我能想到的是,只對條件留住新線,以前符合「@」和當前行開始結束的一個邏輯用「@」表示。 但是,我不確定如何在shell中實現此功能,或者是否可以使用更好的邏輯。

@ 258908159 @ 258908159 @輔助作業= E,Mment = SS09 @ 4 @ 2012年6月5日二十三時24分41秒5 @Jun 2012 23時24分00秒@ 2 @* 「DUMMYI」 U 120605僞數據@ Jun 5 2012 23:26:00 @ 403 @ 21 @ PRCAIE @ 10780093 @ -2 @ @ -1 @ -2 @ 1 @ 35 @ 1 @ @ -1 @ NULL @ -1 @ 154 @ 1 @ 40958044 @ 1 @ 1 @ 3 @ 0 @ -2 @ 1 @ @ 258908158 @ 258908158 @ Subwork = E,Mment = SS09 @ 4 @ Jun 5 2012 23:24:41 @Jun 5 2012 23:24:00 @ 2 @ 3TEST3
結束 @Jun 5 2012 23:26:00 @ 402 @ 21 @ @ 10780093 @ -2 @ @ -1 @ -2 @ 1 @ 35 @ 1 @ @ -1 @ NULL @ -1 @ 154 @ 1 @ 40958044 @ 1 @ 1 @ 3 @ 0 @ -2 @ 0 @

#####新線需要在這裏其他所有新線路必須被移除

@ 258908158 @ 258908158 @輔助作業= E,Mment = SS09 @ 4 @君5 2012 23:24:41 @Jun 5 2012 23:24:00 @ 2 @*「DUMMYI」U 120605 DUMMY @Jun 5 2012 23:26:00 @ 402 @ 21 @ PRCAIE @ 10780093 @ -2 @ -1 @ -2 @ 1 @ 35 @ 1 @ @ -1 @ NULL @ -1 @ 154 @ @ 40958044 @ 1 @ 3 @ 0 @ -2 @ 1 @ @ 258908157 @ 258908157 @ Subwork = E,Mment = SS09 @ 4 @ Jun 5 2012 23:24:41 @Jun 5 2012 23:24:00 @ 2 @ 3TEST3
END @Jun 5 2012 23:26:00 @ 401 @ 21 @ @ 10780093 @ -2 @ @ -1 @ -2 @ 1 @ 35 @ 1 @ @ -1 @ NULL @ -1 @ 154 @ 1 @ 40958044 @ 1 @ 3 @ 0 @ -2 @ 0 @

謝謝。

+0

基於你粘貼的示例文件內容的原始位:在我看來,不可能知道在哪裏放置正確的換行符,因爲沒有可以幫助你識別的「模式」。我看到這個問題的唯一方法就是解決這個問題:你可以計算'@'字符的數量,並在每個'@'後面加一個換行符。 – ArjunShankar

+0

請編輯您的示例輸入/輸出以展示您的需求。 – tuxuday

+0

無法從新輸入(來自** RE-EDITED **部分)獲取'Line1'或'Line2'(如'Line2Col1')。請清楚您希望輸入什麼輸出。 – 2012-06-08 10:21:59

回答

1

我的理解是,我們連接並存儲行。如果當前行以「@」開始,並且存儲的連鎖批次以「@」結尾,則我們處於行邊界。然後我們打印存儲的批次並重新開始。

awk '/^@/ && l~/@$/ { print l; l=$0; next } { l=l $0} END { print l }' 
+1

+1,小簡化:'/^@/&& l〜/ @ $/{print l; l =「」} {l = l $ 0} END {print l}' –

+0

是的,很棒! ;) – Balint

0

這可能會爲你工作:

sed ':a;$bb;N;/@ *\n *@/!{y/\n/ /;ba};:b;P;D' file 

說明:

刪除除了那些@的包圍所有換行符:

  • 製作一個標籤循環::a
  • If last lin e打破第二個標籤b$bb
  • 將下一行添加到模式空間。 N
  • 尋找包含@標誌的換行符。/@ *\n *@/
  • 如果沒有這樣的模式,則將換行符轉換爲空格並循環標記爲a!{y/\n/ /;ba}
  • 找到了模式(所有換行符全部轉換完成)​​或文件結束條件。打印到換行符。 :b;P
  • 刪除上面的打印行並開始新的循環(不要讀取下一行)。 D

一個更隱祕的解決方案:

sed '$!{N;/@ *\n *@/!{s/\(.*\)\n/\n\1/;D}};P;D' file 
0

這個簡單的Perl程序應該做你想要什麼。

它通過連接輸入文件中的行,並在包含一對@符號(可能由空白分隔)的情況下拆分累積字符串來工作。

請注意,它希望輸入文件作爲命令行上的參數,並將修改後的數據發送到STDOUT。

use strict; 
use warnings; 

my $line; 

while (<>) { 
    chomp; 
    $line .= $_; 
    while ($line =~ s/^(.+?\@)\s*(?=\@)//) { 
    print $1, "\n"; 
    } 
} 

print $line, "\n"; 

輸出(使用例如輸入數據)

@Line1Col1 @[email protected] @Line1Col4 @ [email protected] 
@Line2Col1 @Line2Col2 @[email protected]@Line2Col5 @ 

更新

它看起來與你實際文件數據彷彿可以有兩個@一起在一個記錄的中間如此方法以上將無法工作。

但看起來你正在處理@-分離的數據,分析它告訴我,每個記錄有25個字段,即26 @個字符。

該替代程序會累積數據,直到它包含26個或更多@個字符,然後輸出它。它似乎對您發佈的實際數據起作用。

use strict; 
use warnings; 

my $line; 

while (<>) { 
    chomp; 
    $line .= $_; 
    if ($line =~ tr/\@// >= 26) { 
    print ">>", $line, "\n"; 
    undef $line; 
    } 
} 

print $line, "\n" if $line; 
+0

@@將不會有條目,因此您的解決方案都可以工作。我更喜歡由Balint提供的awk解決方案,因爲它可以很容易地集成到我的腳本中。 – girish