回答:
単一ファイルの場合tee
、複数の場所にコピーするために使用できます。
cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>
または、デモ版を好む場合:
tee <outfile1> <outfile2> > <outfile3> < <inputfile>
Dennisがコメントで指摘しているように、リストされたファイルだけでなく、上記の例でファイル3を指すようにリダイレクトを使用tee
しstdout
ていることに注意してください。これを/dev/null
次のようにリダイレクトすることもできます-これには、コマンドラインでファイルリストの一貫性を保つという利点があります(これにより、可変数のファイルのソリューションをスクリプト化するのが簡単になる可能性があります)効率の違いはわずかです:cat
バージョンを使用する場合とバージョンを使用しない場合の違いとほぼ同じですcat
):
cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null
おそらく、上記のfind
いずれかと1つのディレクトリ内の複数のファイルを操作するのは非常に簡単で、ディレクトリ構造全体に広がるファイルを操作するのはそれほど簡単ではないでしょう。それ以外の場合は、複数のコピー操作を個別のタスクとして並行してオフに設定する必要があり、OSディスクキャッシュが明るく、かつ/または並列タスクのそれぞれがドライブヘッドを引き起こす代わりに最初からキャッシュされた読み取りデータを使用するのに十分であることを期待するかもしれませんスラッシング。
可用性:tee
通常、GNU "coreutils"パッケージの一部として、標準のLinuxセットアップおよび他のUNIXまたはUNIXに類似したシステムで一般的に利用可能です。Windowsを使用している場合(質問には明記されていません)、CygwinなどのさまざまなWindowsポートで見つける必要があります。
進捗情報:光メディアから大きなファイルをコピーするには時間がかかる場合があるため(または低速のネットワーク経由、またはローカルの高速メディアからさらに大きなファイルを転送する場合)、進捗情報が役立ちます。コマンドラインでは、パイプビューアーを使用する傾向があります(ほとんどのLinuxディストリビューションおよび多くのWindowsポートコレクションで使用でき、直接使用できない場合は簡単にコンパイルできます)。次のように置き換えcat
てpv
ください。
pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
tee
また、stdoutに出力されることに注意してください。そのtee outputfile1 outputfile2 < inputfile > /dev/null
ため、ターミナルにバイナリファイルを出力するとノイズが多く、設定が混乱する可能性があるため、実行することをお勧めします。
tar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
Windowsの場合:
n2ncopyはこれを行います:
Linuxの場合:
cp
単独のコマンドは、複数の宛先を複数のソースからコピーしたが、残念ながらできません。何らかのループで複数回実行する必要があります。そのようなループを使用して、すべてのディレクトリ名をファイルに配置できます。
OLDIFS=$IFS
IFS=$'\n'
for line in $(cat file.txt):
do
cp file $line
done
IFS=$OLDIFS
またはxargsを使用します。
echo dir1 dir2 dir3 | xargs -n 1 cp file1
これらの両方を使用すると、ディレクトリ全体または複数のファイルをコピーできます。これについては、この StackOverflowの記事でも説明しています。
同様の質問に対する回答に基づいて、別の方法は、GNU Parallelを使用して複数のcp
インスタンスを一度に実行することです。
parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3
上記のコマンドは、file1を3つの宛先フォルダーすべてに並行してコピーします
ライアントンプソンのソリューション:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
非常に理にかなっています:宛先ディレクトリの書き込み速度がほぼ同じ場合、srcfileはディスクから1回だけ読み取られます。残りの時間は、キャッシュから読み取られます。
私はそれをもう少し一般的にするので、サブディレクトリも取得します:
for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;
宛先ディレクトリの書き込み速度が非常に異なる場合(たとえば、1つはRAMディスク上にあり、もう1つはNFS上にある場合)、srcdirをdest1にコピーしている間に読み込まれたsrcdirの部分が書き込み時にディスクキャッシュにないことがわかりますdest2。
この回答によると:https : //superuser.com/a/1064516/702806
よりよい解決策を使用することですtar
とtee
。コマンドはより複雑ですがtar
、転送には非常に強力であるようで、ソースを1回だけ読み取る必要があります。
tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null
スクリプトで使用するには、スクリプトを次のように起動する必要があります。 bash -x script.sh
tar
は、ファイル属性(変更日時、(保護)モード、潜在的にACL、所有者/グループ(特権がある場合)、SELinuxなど)を自動的にコピー(保存)することですコンテキスト(該当する場合)、拡張属性(該当する場合)など)………………PSなぜユーザーが使用する必要があるのbash -x
ですか?
#!/bin/sh
スクリプトの冒頭で使用しましたが、コマンドの構文は受け入れられません。bash -x
または#!/bin/bash
ファイルの先頭で使用できます。解釈sh
とbash
解釈の違いがある理由はわかりません。
bashの場合:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;