私は列166以降の列ヘッダーを取得し、それを各後続の行に印刷するawkスクリプトを使用しています。
前任者。
col165 col166 col167
a 1 2
b 3 4
c 5 6
これになる--
col165 col166 col167
a col166|1 col167|2
b col166|3 col167|4
c col166|5 col167|6
しかし、私が作業しているファイルはかなり大きく(約160万行)、処理に約1.5時間かかります。
プロセスを高速化するために、大容量ファイルを100,000行に分割し、gnuを使用してparallel
各ファイルを個別に処理する方法を考えました。しかし、ファイルのヘッダーを取得してヘッダーをインポートするために使用するスクリプトに問題が発生しました。ヘッダを指定するために別のファイルを使用したいと思います。それ以外の場合は、各分割ファイルにヘッダーを追加する必要があります(それ自体は面倒です)。
私が使用するコードは -
awk 'BEGIN { FS="\t";OFS="\t" };
NR == 1 { split($0, headers); print; next }
{for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1' input > output
column_headers
ファイルを使用してタイトルを指定したいと思います。可能ですか?
次のコードを試しましたが、うまくいかず、コードが正しいかどうかはわかりません。
awk -v head='$(cat column_headers)' 'BEGIN{ FS="\t";OFS="\t" };
NR == 1 { split($head, headers); print; next }
{for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1' input > output
私が何か間違っているような気がしますが、何なのかよくわかりません。私が受けることができるどんな助けにも感謝します。
編集:ありがとう。実際、長期的な犯人だったチェーンのもう一つの命令を逃した。
@Ole Tangeが述べたようにコマンドを使用しましたが、少し修正しました。
time cat input_1|parallel -k -q -j 24 --tmpdir tmp/ --block 900M --pipe awk -f culprit_script > output
スクリプトはデフォルトで各フィールドを分割し、値に応じて削除/保持します。
最初のコマンドを実行するのに約15〜20分かかり、2番目のスクリプトは1時間かかりました。並列性と24スレッドを活用して7分で完了!最初のコマンドにも並列性を使用すると思います。
皆様のご意見やご提案ありがとうございます!
答え1
実際には答えではありませんが、大きすぎて書式が必要なのでコメントできないので...
1.6Mは多くの行数ではありません。おっしゃるとおり、1時間あたり100万行が表示されます。大規模に遅い場合は、1分あたり100万行がより合理的です。たとえば、次のスクリプトを実行して、1行に300列の1,600,000行のファイルを作成しました。
$ awk -v n=1600000 -v c=300 -v OFS='\t' 'BEGIN{for (j=1;j<=c;j++) printf "col%s%s",j,(j<c?OFS:ORS); for (i=1;i<=n;i++) for (j=1;j<=c;j++) printf "%s%s",j,(j<c?OFS:ORS)}' > file
次に、定期的にスクリプトを実行して問題のファイルを変換します。
$ time awk 'BEGIN{FS=OFS="\t"} NR==1{split($0, headers); print; next} {for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1' file > out
real 1m22.569s
user 1m17.971s
sys 0m4.359s
したがって、実行時間は1.5時間ではなく約82秒です。
答え2
GNU Parallelの場合:
#!/bin/bash
do_block() {
awk 'BEGIN{FS=OFS="\t"}
NR==1{split($0, headers); next}
{for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1'
}
export -f do_block
# Non-parallel version
cat file | head -n1 > out1
time cat file | do_block >> out1
# Parallel version
cat file | head -n1 > out2
time parallel -k --pipepart --block -30 -a file --header : do_block >> out2
私の4コアCPUでは、並列バージョンは約3倍高速です。