sedを使用して大容量ファイルヘッダを効率的に削除しますか?

sedを使用して大容量ファイルヘッダを効率的に削除しますか?

次のコマンドは、ファイルのサイズによっては数分かかることがあります。より効率的な方法がありますか?

sed -i 1d large_file 

答え1

次に変更してみてくださいed

ed <<< $'1d\nwq' large_file

「大きい」が約1000万行以上を意味する場合は、使用する方が良いですtail。内部編集はできませんが、パフォーマンス上、これらの欠陥は許すことができます。

tail -n +2 large_file > large_file.new

編集するいくつかの視差を表示します。

awkJaypalが追加したコードは、同じマシン(CPU 2.2GHz)で実行時間があります。)

bash-4.2$ seq 1000000 > bigfile.txt # further file creations skipped

bash-4.2$ time sed -i 1d bigfile.txt
time 0m4.318s

bash-4.2$ time ed -s <<< $'1d\nwq' bigfile.txt
time 0m0.533s

bash-4.2$ time perl -pi -e 'undef$_ if$.==1' bigfile.txt
time 0m0.626s

bash-4.2$ time { tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt; }
time 0m0.034s

bash-4.2$ time { awk 'NR>1 {print}' bigfile.txt > newfile.txt && mv -f newfile.txt bigfile.txt; }
time 0m0.328s

答え2

ファイルの先頭からコンテンツを効率的に削除する方法はありません。データを最初から削除するには、ファイル全体を再作成する必要があります。

しかし、ファイルの終わりから切り取る作業は非常に高速です。 (オペレーティングシステムは単にファイルサイズ情報を調整して現在使用していないブロックを消去することもできます。)ファイルの先頭から削除しようとすると通常は不可能です。

ブロック/範囲全体を正しく削除すると、理論的には「高速」になりますが、システムコールがないため、ファイルシステム固有の意味がある場合はそれに依存する必要があります。 (またはファイルの実際の開始を示すために、最初のブロック/範囲内に何らかの形のオフセットがあるようです。それも聞いたことがありません。)

答え3

最も効果的な方法はしないことです!これにより、とにかく2倍の「大きな」ディスク容量が必要になり、IOを無駄にします。

大きなファイルを見つけて最初の行なしでファイルを読み取るには、読み取るのを待ってから最初の行を削除します。 stdinからプログラムにファイルを送信するには、tailを使用します。

tail -n +2 | your_program

ファイルを読み取る必要がある場合は、最初の行を削除できますが、ディスクに必要なスペースがある場合にのみ可能です。

tail -n +2 | tee large_file2 | your_program

stdinからデータを読み取れない場合は、fifoを使用してください。

mkfifo large_file_wo_1st_line
tail -n +2 large_file > large_file_wo_1st_line&
your_program -i large_file_wo_1st_line

bashを使用している場合は、プロセス置換を活用する方が良いでしょう。

your_program -i <(tail -n +2 large_file)

ファイルで探す必要がある場合は、最初にファイルに閉じ込められているよりも優れた解決策はないと思います。ファイルがstdoutで作成された場合:

large_file_generator | tail -n +2 > large_file

それ以外の場合は、常にfifoまたはプロセス交換ソリューションがあります。

mkfifo large_file_with_1st_file
large_file_generator -o large_file_with_1st_file&
tail -n +2 large_file_with_1st_file > large_file_wo_1st_file

large_file_generator -o >(tail -n 2+ > large_file_wo_1st_file)

答え4

これは理論だけですが…

カスタムファイルシステム(FUSEまたは同様のメカニズムを使用して実装されています)は、コンテンツが他の場所にすでに存在するディレクトリとまったく同じですが、必要に応じてファイルが切り捨てられたディレクトリを公開できます。ファイルシステムはすべてのファイルオフセットを変換します。これにより、時間のかかるファイルの書き換えを実行する必要がなくなります。

しかし、これらのファイルが数十テラバイトに達していない限り、これらのファイルシステムを実装するのは高すぎて時間がかかり、実用的ではないことを考慮することが重要です。

関連情報