たくさんのサブフォルダを含む「foo」フォルダがあります。
foo
|---20101
|---20102
|---20103
|---20111
|---20112
|---20113
これよりはるかに多くのフォルダがありますが、シナリオを説明していると思います。このフォルダから「2011」で始まるすべてのフォルダを「foo」の兄弟である「bar」にコピーしたいと思います。ただし、「bar」にはすでに同じ名前のフォルダがいくつか含まれています。
bar
|---20111
|---20113
|---20114
ソース フォルダーと宛先フォルダーの内容を結合する必要があります。スクリプトでは、bar/20112 フォルダーも作成する必要があることに注意してください。このフォルダーは存在しません。
私はMacターミナルスクリプトの初心者ですが、正しいフォルダをgrepすることに成功しました。
foo>ls | grep ^2011
正しいフォルダーがリストされますが、それを適切なコピー操作にパイプする方法がわかりません。
答え1
コピーコマンドは ですcp
。 (recursive) フラグを指定すると-r
、必要な操作が正確に実行され、既存のフォルダーにファイルをコピーし、コピー先のフォルダーが見つからない場合は新しいフォルダーを作成します。
しかし、出力を解析してはいけませんls
find
、またはもっと簡単に言えば、bash グロブ:
cp -rv foo/2011* bar/
名前が で始まるファイルやフォルダがある場合は2011
、find
とそのオプションを使用します。これにより、 で見つかったすべてのもの( と呼ばれます)-exec
に指定したコマンドが適用されます。find
{}
find foo/ -type d -name "2011*" -exec cp -rv '{}' bar/ \;
この特定のケースでは、コマンドの出力を保存して に渡す理由はありませんcp
。ただし、これは時々必要なので、その方法を説明します。一般に、コマンドの出力は、引用符または で囲むと、別のコマンドの入力として渡すことができます$()
。
cp -rv `find foo/ -type d -name "2011*"` bar/
または
cp -rv $(find foo/ -type d -name "2011*") bar/
あるいは、結果をループすることもできます。
for dir in $(find foo/ -type d -name "2011*"); do cp -rv "$dir" bar/; done
ファイル名やフォルダ名に特殊文字や改行などが含まれる場合はさらに複雑になります。その場合は次のようにします。
find foo/ -type d -name "2011*" | while IFS= read -r dir; do
cp -rv "$dir" bar/;
done