ファイルの先頭からバイトを削除する最良の方法は何ですか?

ファイルの先頭からバイトを削除する最良の方法は何ですか?

今日、私は新しいリポジトリのためにハックしているフィルタリングされたサブバージョンダンプである800MBの混合テキスト/バイナリファイルから最初の1131バイトを削除する必要がありました。最良のアプローチは何ですか?

まず試しました

dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump

ただし、スキップすると、ファイルの残りの部分は一度に1バイトずつコピーされます。つまり、非常に遅いです。最後に、それを3つの512チャンクに丸めるには405バイトが必要であることを知り、スキップできました。

dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump

かなり早く完了しましたが、より簡単でより良い方法がありますか?私が忘れた他のツールはありますか?

答え1

bsを切り替えてオプションをスキップできます。

dd bs=1131 skip=1 if=filtered.dump of=trimmed.dump

これにより、タスクがより大きなチャンクで利点を得ることができます。

それ以外の場合は、tailを試すことができます(バイナリと一緒に使用するのは安全ではありませんが)。

tail -c +1132 filtered.dump >trimmed.dump

最後に、3つのddインスタンスを使用して次のように作成できます。

dd if=filtered.dump bs=512k | { dd bs=1131 count=1 of=/dev/null; dd bs=512k of=trimmed.dump; }

これらのddの1つ目はfilter.dumpを標準出力として印刷し、2つ目は1131バイトのみを読み取り、それを破棄します。最後のddは標準入力からfiltered.dumpの残りのバイトを読み取り、それをクリーンアップされた.dumpに書き込みます。

答え2

いつskip_bytes追加されたのかわかりませんが、最初の11バイトをスキップするには、次の手順を実行します。

# echo {123456789}-abcdefgh- | 
                              dd bs=4096 skip=11 iflag=skip_bytes
-abcdefgh-
0+1 records in
0+1 records out
11 bytes (11 B) copied, 6.963e-05 s, 158 kB/s

where はiflag=skip_bytesdd にオプション値をskipブロックではなくバイトとして解釈するように指示することで簡単にします。

答え3

サブシェルと次の2つの呼び出しを使用できますdd

$ ( dd bs=1131 count=1 of=dev_null && dd bs=4K of=out.mp3 ) < 100827_MR029_LobbyControl.mp3
1+0 records in
1+0 records out
1131 bytes (1.1 kB) copied, 7.9691e-05 s, 14.2 MB/s
22433+1 records in
22433+1 records out
91886130 bytes (92 MB) copied, 0.329823 s, 279 MB/s
$ ls -l *
-rw------- 1 max users 91887261 2011-02-03 22:59 100827_MR029_LobbyControl.mp3
-rw-r--r-- 1 max users     1131 2011-02-03 23:04 dev_null
-rw-r--r-- 1 max users 91886130 2011-02-03 23:04 out.mp3
$ cat dev_null out.mp3 > orig
$ cmp 100827_MR029_LobbyControl.mp3 orig

答え4

使用する必要がありますcount=0。これは可能な限り簡単な方法です。lseek()

このように:

{  dd bs=1131 skip=1 count=0; cat; } <filtered.dump >trimmed.dump

ddlseek()入力ファイル記述子を1131バイトオフセットに移動し、cat残りの内容を出力にコピーするだけです。

関連情報