Text-Processing

awk:按列名拆分文件並將標題行添加到每個文件

  • September 21, 2020

我有一個a.txt包含標題行的管道分隔文件。第一列包含一個文件名。

我想拆分a.txt成幾個不同的文件 - 其名稱由第一列確定。我還想a.txt在每個文件的頂部重複標題行。

所以我有a.txt

filename|count|age
1.txt|1|15
1.txt|2|14
2.txt|3|1
41.txt|44|1
2.txt|1|3

我想創造1.txt

filename|count|age
1.txt|1|15
1.txt|2|14

2.txt

filename|count|age
2.txt|3|1
2.txt|1|3

41.txt

filename|count|age
41.txt|44|1

我有一個基本的拆分工作

awk -F\| '{print>$1}' a.txt

但我正在努力弄清楚如何包含標題,有人可以幫忙嗎?謝謝!

解決方案是將標題儲存在一個單獨的變數中,並在第一次出現新$1值(=文件名)時列印它:

awk -F'|' 'FNR==1{hdr=$0;next} {if (!seen[$1]++) print hdr>$1; print>$1}' a.txt 
  • 這會將整個第一行儲存a.txt在一個變數中hdr,但不處理該特定行。
  • 在所有後續行中,我們首先檢查是否已經遇到該值(=所需的輸出文件名),方法是在一個包含各種值的出現計數的$1數組中查找它。如果目前值的計數器仍然為零,則將標頭輸出到由 指示的文件,然後增加計數器以抑制所有後續出現的標頭輸出。其餘的你自己已經想通了。seen``$1``$1``$1

附錄:

如果您有多個輸入文件,它們都有一個標題行,您可以簡單地將它們全部作為awk呼叫的參數,如

awk -F'|' ' ... ' a.txt b.txt c.txt ...

但是,如果只有第一個文件有標題行,則需要在第一個規則中更改FNR為。NR

警告

正如 Ed Morton 所指出的,這種簡單的方法僅適用於不同輸出文件的數量很小(最多 10 個左右)的情況。GNUawk仍將繼續工作,但會因根據需要在後台自動關閉和打開文件而變得更慢;awk由於“打開的文件太多”,其他實現可能會簡單地失敗。

引用自:https://unix.stackexchange.com/questions/610484