web-dev-qa-db-ja.com

CPを使用して単一のファイルを複数のディレクトリにコピーする

この質問は、以前の質問 mkdirを使用して多数のディレクトリを作成する の続編です。

bashシェルを使用しています。次のコマンドを使用して、それぞれプレフィックス「s」で始まる50個のディレクトリを作成しました。

mkdir $(printf "s%02i " $(seq 1 50))

これにより、2桁目がゼロで埋められます。つまり、取得するディレクトリの形式はs01s02、...、s49s50です。

次に、cpを使用して単一のファイル(たとえば、test.txt)を50個のディレクトリのそれぞれにコピーしたいと思います。上記と同様の方法でこれを行うことは可能ですか?たとえば、次のように機能しますか?私はUnix/Linuxに比較的慣れていないので、誰かがそれが安全であることを教えてくれるまで、私はこれを実際に試したくありません。

cp test.txt $(printf "s%02i.txt" $(seq 1 50))

mancpページを見ると、cpが次のような複数の宛先をサポートしているようには見えません。

NAME
       cp - copy files and directories

SYNOPSIS
       cp [OPTION]... [-T] SOURCE DEST
       cp [OPTION]... SOURCE... DIRECTORY
       cp [OPTION]... -t DIRECTORY SOURCE...

DESCRIPTION
       Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

       Mandatory  arguments  to  long  options are mandatory for short options
       too.
12
Andrew

コマンドの出力を使用して、cpを使用してファイルを各ディレクトリにコピーする場合は、常にxargsにパイプできます。

printf "s%02i " $(seq 1 50) | xargs -n 1 cp test.txt

出力の形式と内容は事前にわかっているので、出力を解析する際の安全性について心配する必要はありません。ファイル名にメタ文字とスペースが含まれるリスクは、ここでは問題になりません。

または、ディレクトリがすでに存在すると仮定して、次のようなことを試すことができます。

find . -maxdepth 1 -type d -name 's[0-9][0-9]' -print0 | xargs -0 -I {} cp test.txt {}

またはパイプなし:

find . -maxdepth 1 -type d -name 's[0-9][0-9]' -exec cp test.txt {} \;

最後の2つのコマンドは、現在のディレクトリ内のすべてのファイルを検索し、それらにcptest.txtします。 -maxdepth 1オプションは、ファイルを受信するサブディレクトリも回避します。 's[0-9][0-9]'sに一致し、その後に任意の2桁が続くことに注意してください。これは、何らかの理由でcwds99がある場合、 test.txtのコピー。

7
tojrobinson

シェルにforループを使用して反復を行わせることもできます。これは、parallelxargsなどの外部ツールに依存しない最も基本的な方法であり、理解するのが最も簡単です。

for name in $(printf "s%02i " $(seq 1 50)); do
    mkdir $name
    cp test.txt $name
done

これを書く方法は他にも100万通りあります。例えば:

for name in $(seq -w 1 50); do
    mkdir s$name
    cp test.txt s$name
done

実行前に何が実行されるかを確認したい場合は、コマンドの前にechoを付けるなどして、実行するのではなく行を出力します。

for name in $(seq -w 1 50); do
    echo mkdir s$name
    echo cp test.txt s$name
done

出力:

mkdir s01
cp test.txt s01
mkdir s02
cp test.txt s02
mkdir s03
cp test.txt s03
# etc.
8
Jim Paris

これによると: https://stackoverflow.com/questions/195655/how-to-copy-a-file-to-multiple-directories-using-the-gnu-cp-command それは1つのファイルを複数の宛先にコピーすることはできません。これを行う別の方法を示しているので、リンクを確認してください。

4
user23809

GNU parallel を使用することもできます。text.txtを含むディレクトリにあり、50個のディレクトリが/my/50dirs/path (お気に入り /my/50dirs/path/s01/my/50dirs/path/s02 etc)実行します:

seq -w 01 50 | parallel -j1 cp text.txt /my/50dirs/path/s{}
2
don_crissti