2014-01-21 25 views
0

我想在55個「顯示」行之後分割一個文本文件(1000-2000行)。要計算顯示的行的實際數目,Bash:在正則表達式匹配之前分割文本文件

grep -n "^L 7p 39 C\|^N 2" airportdata.txt | cut -f1 -d: >> matches_all.txt

作品所需。

現在我有顯示的行的總數,包括「顯示的內容」所在的行號。

我的問題:我只允許在N 2之前拆分文件(請參閱示例內容)以保留文件結構。我不知道如何實現這一點。我的嘗試是看比賽號碼是否是N 2。然後拆分很容易:

head -55 airportdata.txt > apd_1.txt 
tail -n +55 airportdata.txt > apd_2.txt 

在保持文件結構完好無損的情況下做到了這一點。

如果我匹配其他行之一,我必須在文件中「走」,並找到一個行數較低的行,其行數爲N 2,並在那裏分割文件。而這正是我迄今爲止沒有成功的部分。

任何想法非常受歡迎。

一切順利,

克里斯


文件結構: N n定義列數。以下行分配到這些列中,直到新的N n發生變化。

N 2表示兩列,所以接下來的兩行構成一個「顯示行」。

N 9表示九列,每九行後面組成一個「顯示行」。

樣本內容airportdata.txt的:

N 2 
L 7p 40 L @:6.5p:[email protected]:: 
L 7p 39 R 1410ft/nil 
N 9 
L 7p 39 L 1 
L 7p 39 L 16 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 2500*x61 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 34 
L 7p 39 R - 
N 2 
L 7p 40 L @:6.5p:[email protected]:: 
L 7p 39 R 1890ft/nil 
N 9 
L 7p 39 L 1 
L 7p 39 L 11L 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 2500 x46 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 29R 
L 7p 39 R 1 
L 7p 39 L G 
L 7p 39 L 11R 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 2200 x46 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 29L 
L 7p 39 R G 
N 2 
L 7p 40 L @:6.5p:[email protected]:: 
L 7p 39 R 10ft/n.a 
N 9 
L 7p 39 L 3 
L 7p 39 L 08L 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 3000 x61 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 26R 
L 7p 39 R 3 
L 7p 39 L 3 
L 7p 39 L 08R 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 3500*x61 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 26L 
L 7p 39 R 1 
L 7p 39 L 1 
L 7p 39 L 12 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 2200 x61 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 30 
L 7p 39 R G 
N 2 
L 7p 40 L @:6.5p:[email protected]:: 
L 7p 39 R 780ft/8 
N 9 
L 7p 39 L 2 
L 7p 39 L 36 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 3300 x61 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 18 
L 7p 39 R V 
L 7p 39 L 1 
L 7p 39 L 13 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 2600 x61 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 31 
L 7p 39 R 1 

適應於所述樣品的內容的可能的結果將是:4中顯示的行

apd_1.txt後分裂:

N 2 
L 7p 40 L @:6.5p:[email protected]:: 
L 7p 39 R 1410ft/nil 
N 9 
L 7p 39 L 1 
L 7p 39 L 16 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 2500*x61 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 34 
L 7p 39 R - 

條件

apd_2.txt

N 2 
L 7p 40 L @:6.5p:[email protected]:: 
L 7p 39 R 1890ft/nil 
N 9 
L 7p 39 L 1 
L 7p 39 L 11L 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 2500 x46 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 29R 
L 7p 39 R 1 
L 7p 39 L G 
L 7p 39 L 11R 
L 7p 39 L \040 
L 7p 39 L \040 
L 7p 39 C 2200 x46 
L 7p 39 R \040 
L 7p 39 R \040 
L 7p 39 R 29L 
L 7p 39 R G 
[and all the rest] 

第五匹配的行不N 2,因此切在以前N 2

+0

想幫助,但我不認爲我完全理解這個問題。就像一個提示:Csplit可能在這裏有所幫助:http://man7.org/linux/man-pages/man1/csplit.1.html –

+1

如果你重寫你的問題爲5行,而不是56行,它將是方便人們可視化你要求的結果。祝你好運。 – shellter

+0

你是不是固定在bash上?在perl或ruby中你可以更容易做一些展望。 –

回答

0

不知道我理解你所有的條件面前做出,但我認爲最簡單的是使用循環,例如

#!/bin/bash 
apd=0 
while read line; do 
    [[ $line == "N 2"* ]] && apd=$(($apd+1)) 
    echo "$line" >> "add_${apd}.txt" 
done < "airportdata.txt"  

其中關於你的樣品aiportdata.txt將輸出4個文件add_1.txt add_2.txt add_3.txt add_4.txt每個開始N 2

+0

這在每次提及'N 2'時都很好地分割了文件。理想的結果是在'N 2'前面的一個分割線,在'matches_all.txt'文件中有一個行號= <. – Chris

+0

@Chris所以基本上它應該每隔56行分割一次或者遇到'N 2'? – BroSlow

+0

並非如此 - 我儘量以另一種方式解釋它:文件'airportdata.txt'用於填充最大容量爲55行的框。文件中的每一行都不會被打印出來,因爲這些行被解析爲多個列,並且文件只能以'N 2'分割。這可能會導致「可見」行數小於55(在框中少於55行)。問題中的「grep」是一個近似值:它匹配9列線的中間列和開始新機場集。但結果足夠接近作爲指導。 – Chris

0

如果我理解正確,那麼你正在尋找的東西是這樣的:

awk -v n=55 -v f1=apd_1.txt -v f2=apd_2.txt ' 
    /^N/ {++c} 
    c <= n { print > f1 } 
    c > n { print > f2 } 
' < airportdata.txt 

這就是:

  • 將一些變量傳遞給awkn =「門檻」數來分割,f1f2所述兩個輸出文件
  • 如果行開頭N,增加計數
  • 如果計數小於或等於閾值時,打印到第一文件
  • 如果計數大於閾值,打印到第二個選項
+0

謝謝你的解釋。不幸的是,這不是我正在尋找的分割。只是尋找「N n」事件並不會削減它。 'n = 55'對'matches_all.txt'中的所有結果行都有效。但是隻有下一行是'N 2'時才能切割。所以它變得更加n = <55。對不起我的英語不好。 – Chris

+0

@Chris在我看來,通過調整那裏的n = 55設置(改爲'n = 56'或'n = 54'?),或者通過調整'c <= n', 'c > n '裏面的條件。沒有? – janos

+0

享受無限循環getline將提供某一天,當你最不期待的時候:-)。閱讀http://awk.info/?tip/getline,並確保在使用getline之前完全理解所有注意事項。 –