この質問は、以前の質問 mkdir
を使用して多数のディレクトリを作成する の続編です。
bash
シェルを使用しています。次のコマンドを使用して、それぞれプレフィックス「s」で始まる50個のディレクトリを作成しました。
mkdir $(printf "s%02i " $(seq 1 50))
これにより、2桁目がゼロで埋められます。つまり、取得するディレクトリの形式はs01
、s02
、...、s49
、s50
です。
次に、cp
を使用して単一のファイル(たとえば、test.txt
)を50個のディレクトリのそれぞれにコピーしたいと思います。上記と同様の方法でこれを行うことは可能ですか?たとえば、次のように機能しますか?私はUnix/Linuxに比較的慣れていないので、誰かがそれが安全であることを教えてくれるまで、私はこれを実際に試したくありません。
cp test.txt $(printf "s%02i.txt" $(seq 1 50))
man
のcp
ページを見ると、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.
コマンドの出力を使用して、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つのコマンドは、現在のディレクトリ内のすべてのファイルを検索し、それらにcp
test.txt
します。 -maxdepth 1
オプションは、ファイルを受信するサブディレクトリも回避します。 's[0-9][0-9]'
はs
に一致し、その後に任意の2桁が続くことに注意してください。これは、何らかの理由でcwd
にs99
がある場合、 test.txt
のコピー。
シェルにfor
ループを使用して反復を行わせることもできます。これは、parallel
やxargs
などの外部ツールに依存しない最も基本的な方法であり、理解するのが最も簡単です。
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.
これによると: https://stackoverflow.com/questions/195655/how-to-copy-a-file-to-multiple-directories-using-the-gnu-cp-command それは1つのファイルを複数の宛先にコピーすることはできません。これを行う別の方法を示しているので、リンクを確認してください。
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{}