3

大きなファイル (1Gb) があり、レコード番号を使用して数行を抽出する必要があります。スクリプトを sed で書いたのですが、時間がかかりすぎたので調査することにしました。sed -n '15689,15696p' filename のようなものを実行すると、印刷は高速ですが、その後に時間の遅延があり、スクリプトが非常に遅くなることがわかりました。awk で同じタスクを実行すると、遅延は小さくなりますが、まだ残っています! awk に使用したコマンド ラインは次のとおりです。 awk 'NR>=15689 && NR<=15696' filename

1 行 (sed -n '15689p' ファイル名) だけを印刷しようとしましたが、同じ問題が発生しました。

誰もそれを見たことがなく、このばかげた遅延を取り除く方法を知っているのではないかと思います. この遅延は印刷タスクの後に発生するため、これは大きな問題のように思えます。私はすでにこのフォーラムや他のフォーラムを検索しましたが、この問題に関する質問は見当たりませんでした。誰かが私を助けることができますか?ありがとう

4

2 に答える 2

3

ファイルの最後までスキャンするためです。印刷後に終了するには、これを試してください:

sed -ne '15690q;15689p' file

または awk を使用:

awk 'NR>=15689 && NR<=15696{print} NR==15697{exit}' filename

キックのために、 @RichardHum のタイミングを実行しましたが、SSD ドライブを搭載した OSX Mavericks ではまったく逆です。

#!/bin/bash -xv
seq 1 100000000 > file
time (head -50000000 file | tail -10) > /dev/null
time (sed -n '50000000q;49999991,50000000p' file) > /dev/null
time (awk 'NR>=49999991 && NR<=50000000{print} NR==50000001{exit}' file)
time (head -50000000 file | tail -10) > /dev/null

そして私は得ました:

time (head -50000000 file | tail -10) > /dev/null
real    0m29.565s
user    0m35.711s
sys 0m0.733s

time (sed -n '50000000q;49999991,50000000p' file) > /dev/null
real    0m13.313s
user    0m13.162s
sys 0m0.150s

time (awk 'NR>=49999991 && NR<=50000000{print} NR==50000001{exit}' file)
real    0m7.433s
user    0m7.293s
sys 0m0.139s

time (head -50000000 file | tail -10) > /dev/null
real    0m29.560s
user    0m35.697s
sys 0m0.742s

初めてキャッシュする利点がなかった場合に備えて、最後に頭と尾のソリューションを実行しましたが、間違いなく何マイルも遅くなります!

于 2014-05-27T14:12:21.063 に答える
3

sed -n '15689,15696p'sed はファイル全体を処理するため、使用しないでください。私が知っている最速の方法はこれです:

head -15696 filename | tail -10

私はそれをベンチマークしました、そしてそれはずっと速く走ります:

$ seq 1 100000000 > file

$ time (head -50000000 file | tail -10) > /dev/null
real    0m0.694s
user    0m0.830s
sys     0m0.333s

$ time (sed -n '49999991,50000000p' file) > /dev/null
real    0m6.018s
user    0m5.863s
sys     0m0.160s

$ time (sed -n '50000000q;49999991,50000000p' file) > /dev/null
real    0m3.197s
user    0m3.153s
sys     0m0.043s

$ time (awk 'NR>=49999991 && NR<=50000000' file) > /dev/null
real    0m12.665s
user    0m12.543s
sys     0m0.123s

$ time (awk 'NR>=49999991 && NR<=50000000{print} NR==50000001{exit}' file)
real    0m9.104s
user    0m9.010s
sys     0m0.100s
于 2014-05-27T14:14:50.737 に答える