web-dev-qa-db-ja.com

gnu cpコマンドを使用してファイルを複数のディレクトリにコピーする方法

Cpコマンドを使用して単一のファイルを複数のディレクトリにコピーすることは可能ですか?

私は次のことを試しましたが、うまくいきませんでした:

cp file1 /foo/ /bar/
cp file1 {/foo/,/bar}

Forループまたはfindを使用することが可能であることを知っています。しかし、gnu cpコマンドを使用することは可能ですか?

199
Tom Feiner

いいえ、cpは複数のソースをコピーできますが、単一の宛先にのみコピーします。目的に合わせて、cpを複数回(宛先ごとに1回)呼び出すように手配する必要があります。あなたが言うように、ループまたは他のツールを使用します。

103
moonshadow

cpだけではこれを行えませんが、cpxargsと組み合わせることができます。

echo dir1 dir2 dir3 | xargs -n 1 cp file1

file1dir1dir2、およびdir3にコピーします。 xargscpを3回呼び出してこれを行います。詳細については、xargsのマニュアルページを参照してください。

568
Robert Gamble

ワイルドカードはロバーツコードでも動作します

echo ./fs*/* | xargs -n 1 cp test 
76
Paul

私が見る限り、次のものを使用できます:

ls | xargs -n 1 cp -i file.dat

cpコマンドの-iオプションは、現在のディレクトリのファイルをfile.datで上書きするかどうかを尋ねられることを意味します。完全に自動化されたソリューションではありませんが、私にとってはうまくいきました。

19
Evgeny
17
deterb

これらの答えはすべて、明白なものよりも複雑に見えます。

for i in /foo /bar; do cp "$file1" "$i"; done
9
Waxrat

ls -db di*/subdir | xargs -n 1 cp File

-bがある場合ディレクトリ名にスペースそれ以外の場合、xargsによって別のアイテムとして破損し、エコーバージョンでこの問題が発生しました。

9
thAAAnos

Cp自体は使用しませんが、...

これは、多くのGopro映像を(遅い)SDカードから3つの(遅い)USBドライブにコピーするという文脈で思い浮かびました。永遠にかかったので、一度だけデータを読みたかった。そして、私はそれを再帰的にしたかった。

$ tar cf - src | tee >( cd dest1 ; tar xf - ) >( cd dest2 ; tar xf - ) | ( cd dest3 ; tar xf - )

(さらに出力が必要な場合は、これらの>()セクションをさらに追加できます。)

私はそれをベンチマークしていませんが、cp-in-a-loop(または多数の並列cp呼び出し)よりも明らかに高速です。

6
oggust

Mac OSでワイルドカードを使用してxargsを使用してディレクトリにコピーを使用する場合、ディレクトリ名にwithスペースが機能する唯一の解決策は次のとおりです。

find ./fs*/* -type d -print0 | xargs -0 -n 1 cp test 

testはコピーするファイルです
そして_./fs*/*コピー先のディレクトリ

問題は、xargsがスペースを新しい引数として認識し、-dまたは-Eを使用して区切り文字を変更する解決策がMac OSで正しく動作しないことです。

4
MegaCookie

分岐したコマンドなしでそれをしたい場合:

tee <inputfile file2 file3 file4 ... >/dev/null

3
Taywee

基本的にxargsの回答と同等ですが、並列実行が必要な場合:

parallel -q cp file1 ::: /foo/ /bar/

したがって、たとえば、file1を現在のフォルダーのすべてのサブディレクトリにコピーするには(再帰を含む):

parallel -q cp file1 ::: `find -mindepth 1 -type d`

N.B .:これはおそらく、非常に特定のユースケースの顕著な速度向上のみを伝えます。各ターゲットディレクトリが個別のディスクである場合。

また、機能的にはxargsの '-P'引数に似ています。

2
alainv

Bashスクリプトを使用する

DESTINATIONPATH[0]="xxx/yyy"
DESTINATIONPATH[1]="aaa/bbb"
                ..
DESTINATIONPATH[5]="MainLine/USER"
NumberOfDestinations=6

for (( i=0; i<NumberOfDestinations; i++))
    do
        cp  SourcePath/fileName.ext ${DESTINATIONPATH[$i]}

    done
exit
1
Patrick Manley
ls -d */ | xargs -iA cp file.txt A
0
Sj Lee

fileName.txtを現在の作業ディレクトリ内のすべてのサブディレクトリにコピーするとします。

  1. lsを介してすべてのサブディレクトリ名を取得し、allFolders.txtなどの一時ファイルに保存します

    ls > allFolders.txt
    
  2. リストを印刷して、コマンドxargsに渡します。

    cat allFolders.txt | xargs -n 1 cp fileName.txt
    
0
Devendra Lattu

いいえ、あなたがすることはできません。

複数の機会にこの機能を使用できることがわかったため、これを行うための独自のツールを作成しました。

http://github.com/ddavison/branch

ものすごく単純 -
branch myfile dir1 dir2 dir3

0
ddavison

別の方法は、次のように猫とティーを使用することです。

cat <source file> | tee <destination file 1> | tee <destination file 2> [...] > <last destination file>

ただし、ジョブは複数のプロセス(宛先ごとに1つ)に分割され、ハードドライブはプラッターの異なる部分に一度に複数のファイルを書き込むため、これはかなり非効率的だと思います。ただし、複数の異なるドライブにファイルを書き出す場合、この方法はおそらく非常に効率的です(すべてのコピーが同時に発生する可能性があるため)。

0
user168046

すべてのターゲットディレクトリがパス式に一致する場合(すべてがpath/toのサブディレクトリであるように)、次のようにfindと組み合わせてcpを使用します。

find ./path/to/* -type d -exec cp [file name] {} \;

それでおしまい。

0
Mig82