awkでファイルを分割すると、最後の行が正しくありません。

awkでファイルを分割すると、最後の行が正しくありません。

main.txt以下のデータファイルがあります。

20130826,aaaaaaaaaaaaaa,bbbbbbb
20130826,sdfasdfasdfas,sdfasdfasd
20130826,dfasdfas,asdf2323
...
20130827,sfasdfasdfasd,sdfasdfwea

私はmain.csv日付ごとに小さなファイルに分割するために次のawkフラグメントを使用しています。

cat test01 | stdbuf -oL -eL awk -F',' '{print $2","$3 >> "data"$1".csv"; fflush()}'

分割ファイルdata20130826.csvの最後の行が不完全であることがわかりました。

...
20130826,dfasdfas,asdf2323
2013082

実際、日付20130826の最後の数行(約10行)が欠落しており、data20130827.csvにありません。バッファリングをオフにするために上記の行に沿ってみましたが、役に立たないようです。メインファイルは大丈夫だと思います。何が間違っていますか?私はGNU Awk 4.0.1を使用しています。

ベストアンサー1

私の元の投稿を明確にするために:私はOrionのコメントに同意し、これは奇妙なバグだと思います。私はfflushにも気にしません。私はこれがデータによる奇妙な問題だと思います。特に、ファイルの各日付に1つずつ開いているファイル記述子が多すぎるようです。あるいは、同じ理由でバッファ制限に達した可能性があります。開いているファイルが多すぎます。 fflush は開いたファイルを閉じずにバッファをフラッシュします。

それでは、入力ファイルにはいくつかの異なる日付がありますか?以下は開いているファイルの数です。

cut -d"," -f1 test01 | sort | uniq | wc -l

- ファイルが何百もの場合は、いつでもファイルを閉じるための2番目の提案を参照してください。

2つの提案:
1.データが隠された文字(バックスペースなど)なしでプレーンテキストであり、通常のUNIX行末を含みますか? 「20130826」というプレフィックスが付いた行を見つけて正常に見え、実際にはすべて別々の行かどうかを確認できますか?

cat test01 | grep "^20130826"
- and also run
cat test01 | grep -c "^20130826"

- grep行番号が出力ファイルの内容と一致する(または一致しない)ことを確認してください。

2. 入力データが日付順にソートされている場合は、ファイルの作成中にファイルを閉じて表示できます。もともと投稿以来これをテストしましたが、うまくいきました。

cat test01 | awk -F"," '{prevfile=ofile; ofile=sprintf("data%s.csv",$1);
             if (NR > 1 && ofile != prevfile) close(prevfile); print $2","$3 >> ofile}'

ファイルが日付でソートされていない場合でも、このコードは機能しますが、ファイルをより頻繁に開閉します。この場合、コマンドの先頭で「cat test01」を「sort test01」に変更するだけです。

awkを使用するときは常に明示的にファイルを閉じる必要はありませんが、私の経験では、これらのファイルを閉じずにたくさん書くと、awkがクラッシュする可能性があります。これは私の考えにまだ当てはまります。ファイル記述子を開きます。

また、これらのファイルに追加するときは、コマンドを実行する前にファイルにデータが含まれていないことを確認してください。仕事がうまくいかないと忘れてしまいやすいです。

おすすめ記事