awk: ファイルを列名に分割し、各ファイルにヘッダー行を追加します。

awk: ファイルを列名に分割し、各ファイルにヘッダー行を追加します。

ヘッダー行を含むパイプで区切られたファイルがあります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

解決策は、ヘッダーを別の変数に保存し、$1新しい値(= filename)が最初に表示されたときに印刷することです。

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 ...

ただし、最初のファイルにのみヘッダー行がある場合は、最初のルールでそれを変更する必要がありますFNRNR

警告する

Ed Mortonが指摘したように、この単純なアプローチは、さまざまな出力ファイルの数が少ない場合(最大10個)でのみ機能します。 GNUはawkまだ動作しますが、必要に応じてバックグラウンドでファイルを自動的に閉じて開くため、遅くなります。他のawk実装では、「開いたファイルが多すぎて失敗する」ことがあります。

おすすめ記事