web-dev-qa-db-ja.com

dd:複数の入力ファイル

2つのファイルからチャンクを連結する必要があります。

ファイル全体を連結する必要がある場合は、簡単にできます

cat file1 file2 > output

しかし、最初のファイルから最初の1 MBをスキップする必要があり、2番目のファイルからは10 MBしか必要ありません。 ddの仕事のようですね。

dd if=file1 bs=1M count=99 skip=1 of=temp1
dd if=file2 bs=1M count=10 of=temp2
cat temp1 temp2 > final_output

これを1つのステップで実行する可能性はありますか?つまり、中間結果を保存する必要はありませんか? ddで複数の入力ファイルを使用できますか?

14
Martin Vegter

ddもstdoutに書き込むことができます。

( dd if=file1 bs=1M count=99 skip=1
  dd if=file2 bs=1M count=10  ) > final_output
21
meuh

単一のdd呼び出しで複数のファイルを簡単に読み取ることはできないと思いますが、いくつかの手順で追加して出力ファイルを構築できます。

dd if=file1 bs=1M count=99 skip=1 of=final_output
dd if=file2 bs=1M count=10 of=final_output oflag=append conv=notrunc

両方を指定する必要がありますconv=notruncおよびoflag=append。 1つ目は出力の切り捨てを回避し、2つ目は既存のファイルの最後から書き込みを開始します。

10
Stephen Kitt

ddread()write()およびlseek()システムコールへの生のインターフェースであることを覚えておいてください。通常のファイル、ブロックデバイス、一部のキャラクターデバイス(/dev/urandomなど)からデータのチャンクを抽出する場合にのみ確実に使用できます。つまり、read(buf, size)sizeを返すのは、ファイルに到達していません。

パイプ、ソケット、ほとんどのキャラクターデバイス(ttyなど)では、サイズ1のread() sを実行するか、GNU dd拡張iflag=fullblockを使用しない限り、このような保証はありません。

だからどちらか:

{
  gdd < file1 bs=1M iflag=fullblock count=99 skip=1
  gdd < file2 bs=1M iflag=fullblock count=10
} > final_output

または:

M=1048576
{
  dd < file1 bs=1 count="$((99*M))" skip="$M"
  dd < file2 bs=1 count="$((10*M))"
} > final_output

または、ksh93のようなシーク演算子の組み込みサポートを備えたシェルを使用します。

M=1048576
{
  command /opt/ast/bin/head -c "$((99*M))" < file1 <#((M))
  command /opt/ast/bin/head -c "$((10*M))" < file2
}

またはzsh(ここでhead-cオプションをサポートしている場合):

zmodload zsh/system &&
{
  sysseek 1048576 && head -c 99M &&
  head -c 10M < file2
} < file1 > final_output
8

bashism、および機能的には「役に立たないcatの使用はありますが、 OPが使用する構文:

cat <(dd if=file1 bs=1M count=99 skip=1) \
    <(dd if=file2 bs=1M count=10) \
   > final_output

(とは言っても、Stephen Kittの答えは、効率的な可能な方法のようです。)

3
agc