2016-04-18 122 views
0

我有兩個文本文件,每個文本文件都包含一個由空行分隔的文本塊。塊的大小各不相同。按塊合併兩個文本文件

# ::id 10 
# ::snt Yes ! 
...multiple lines of unstructured data from file 1... 

# ::id 11 
# ::snt said Lion . 
...multiple lines of unstructured data from file 1... 

# ::id 12 
# ::snt Yes yes ! 
...multiple lines of unstructured data from file 1... 

# ::id 13 
# ::snt said Tiger . 
...multiple lines of unstructured data from file 1... 

,同樣另一

# ::id 10 
# ::snt No ! 
...multiple lines of unstructured data from file 2... 

# ::id 11 
# ::snt said Monkey . 
...multiple lines of unstructured data from file 2... 

# ::id 12 
# ::snt No no ! 
...multiple lines of unstructured data from file 2... 

# ::id 13 
# ::snt said Donkey . 
...multiple lines of unstructured data from file 2... 

我要合併的兩個街區,但他們的# ::id排序。另外,我需要在file2數據塊之前保留file1數據塊的順序。所以最終輸出應該是這樣的:

# ::id 10 
# ::snt Yes ! 
...multiple lines of unstructured data from file 1... 

# ::id 10 
# ::snt No ! 
...multiple lines of unstructured data from file 2... 

# ::id 11 
# ::snt said Lion . 
...multiple lines of unstructured data from file 1... 

# ::id 11 
# ::snt said Monkey . 
...multiple lines of unstructured data from file 2... 

# ::id 12 
# ::snt Yes yes ! 
...multiple lines of unstructured data from file 1... 

# ::id 12 
# ::snt No no ! 
...multiple lines of unstructured data from file 2... 

# ::id 13 
# ::snt said Tiger . 
...multiple lines of unstructured data from file 1... 

# ::id 13 
# ::snt said Donkey . 
...multiple lines of unstructured data from file 2... 

我該怎麼做?任何將工作bashsedawk

+1

'awk'允許您使用正則表達式作爲記錄分隔符(RS)。例如,您可以將文件讀取到數組中,並使用'asort'對其進行排序。 –

+0

您能否提供語法?我的'awk'有點生疏。問題是我想將這兩個文本文件合併爲一個。我怎麼做? – Sudhi

+0

基本思想是將兩個文件讀入數組並對其進行排序。但是,如果文件非常大,那將不是有效的策略。 –

回答

1
$ awk -v RS= -v ORS='\n\n' 'NR==FNR{a[NR]=$0;next} {print a[FNR] ORS $0}' file1 file2 
# ::id 10 
# ::snt Yes ! 

# ::id 10 
# ::snt No ! 

# ::id 11 
# ::snt said Lion . 

# ::id 11 
# ::snt said Monkey . 

# ::id 12 
# ::snt Yes yes ! 

# ::id 12 
# ::snt No no ! 

# ::id 13 
# ::snt said Tiger . 

# ::id 13 
# ::snt said Donkey . 

上述讀取的文件的內容的一個段落在一個時間到數組a[]由鏈條,其中的段落中的文本塊中分離2個空白行(設置RS爲空)。當它讀取第一個文件時,它只是將它們存儲在數組0122中,然後在讀取第二個文件時,將所有文件1讀取到a[]中,然後首先從file1(a[paragraph number])打印相應的段落,然後從file2打印當前段落。

+1

謝謝!這工作。我用更多的信息更新了我的問題。但我想你理解了這一點的_merge_方面。 – Sudhi

+0

如果你有一些時間,我會很感激它的解釋。總是樂於學習:-) – Sudhi

+1

我在最後添加了一個解釋。我推薦Arnold Robbins編寫的第4版Effective Awk Programming。 –

1

說:awk -f merge.awk file1 file2

BEGIN { RS="" } 
{ ARR[NR] = $0 } 
END { 
    n = asort(ARR); 
    for (i = 1; i <= n; i++) 
     print ARR[i]; 
} 
+0

這可能比預期的排序要多,因爲它將在排序時使用段落的全部內容。你可以通過id在'ARR'中存儲(並附加到值)以避免這種情況。 –

+0

謝謝!非常有幫助。但是,分段函數會擾亂文件的順序。我想從file1開始第一個塊,從file 2開始第二個塊,但是它以相反的順序返回。我嘗試重新排序文件,但沒有運氣。它看起來像'asort'函數將數組排序爲字符串。所以如果來自'file2'的塊是_stringwise_更小,那麼它將首先出現。任何關於如何解決這個問題的指針? – Sudhi

+0

err,關於如何存儲塊和id的任何指針?我可以處理記錄兩次嗎? – Sudhi

0

你可以做到這一點使用sedsort

sed '/# ::id/N;s/\n/ /;/^$/d' file1 file2 | sort -s -n -k3,3 | sed 's/\(# ::snt.*\)/\n\1\n/' 

第一sed部分與接合線下一行在一起一個包含# ::id並刪除空行。

然後將結果按表達式# ::id xx(第3個參數)的標識號排序。

最後行被切割在其中# ::snt發現

+0

謝謝!但是'#:: snt'行之後還有幾行(非結構化的)。我如何捕獲所有這些? – Sudhi

+0

我用更多信息更新了我的問題。 – Sudhi

0

此相匹配的記錄由IDS號碼情況下,他們沒有在這兩個文件

$ awk -F'\n' -v RS= 'NR==FNR{a[$1]=$0; next} 
          {printf "%s\n\n%s\n\n",a[$1],$0}' file1 file2 

# ::id 10 
# ::snt Yes ! 
...multiple lines of unstructured data from file 1... 

# ::id 10 
# ::snt No ! 
...multiple lines of unstructured data from file 2... 

# ::id 11 
# ::snt said Lion . 
...multiple lines of unstructured data from file 1... 

# ::id 11 
# ::snt said Monkey . 
...multiple lines of unstructured data from file 2... 

# ::id 12 
# ::snt Yes yes ! 
...multiple lines of unstructured data from file 1... 

# ::id 12 
# ::snt No no ! 
...multiple lines of unstructured data from file 2... 

# ::id 13 
# ::snt said Tiger . 
...multiple lines of unstructured data from file 1... 

# ::id 13 
# ::snt said Donkey . 
...multiple lines of unstructured data from file 2... 

可以增強file2中趕上缺失的記錄,以及對齊。