
今日、私は新しいリポジトリのためにハックしているフィルタリングされたサブバージョンダンプである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_bytes
dd にオプション値を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
dd
lseek()
入力ファイル記述子を1131バイトオフセットに移動し、cat
残りの内容を出力にコピーするだけです。