Bashスクリプトで以下のようなコマンドを実行しようとしています。すべてのサブフォルダを検索し$sourcedir
、特定の種類のすべてのファイルをルートレベルにコピーする必要があります$targetdir
。
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
渡され{}
ないという点を除けばかなり近いようです。$2
-exec sh -c ...
私はできるだけ「正しい方法」に近づき、ファイル名の特殊文字(特に一重引用符文字)を許可したいと思います。
編集する:xargs
誰かがパラメータチェーンの使用を提案しているのを見ました。私の考えでは、これは限られた数のパラメータでのみ機能するということです。たとえば、複数のギャラリーディレクトリから巨大なスライドショーディレクトリにコピーしたい数千の.jpgファイルがある場合、リンクパラメータソリューションは引き続き機能しますか?
編集2:_
私の問題は、コマンドの最初のオプションshの前にaがないことです-exec
。 findコマンドをどのように機能させるかについて疑問に思う人は、次のものを追加するとすべてがうまくいく_
でしょう。
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
以下の回答は同じことを行いますが、より効率的でエレガントなので受け入れました。
答え1
特定の種類のファイルを特定のディレクトリにコピーしますか?これを行う方が優れているxargs
必要はありませんsh
。これはより適切なアプローチであり、より効率的に実行する必要があります。
find "$sourcedir" -type f -name "*.type" | xargs cp -t targetdir
特殊ファイル名を処理する必要がある場合はNULL
区切り文字として使用
find "$sourcedir" -type f -name "*.type" -print0 | xargs -0 cp -t "$targetdir"
答え2
{}
これをシェルに引数として渡し、各引数を繰り返す必要があります。
find "$sourcedir" -type f -name "*.type" -exec sh -c 'for f; do cp "$f" "$0"; done' "$targetdir" {} +
ノート: 仕組みは、シェルの最初の引数が次のようになることです。シェル名、名前をとして渡し、シェルスクリプトの特殊パラメータを使用してそのターゲットディレクトリにアクセスすることで$targetdir
これを利用できます。$0
答え3
xargs教会を信じていない場合:
find "$sourcedir" -type f -name "*.mp3" -exec cp -t "$targetdir" {} +
説明する:
cp -t a b c d
b、c、dをターゲットディレクトリaにコピーします。
-exec cmd {} +
順番にコマンドを呼び出すのではなく、一度に複数のファイルに対してコマンドを呼び出します(";"
代わりに使用する場合は標準です+
)。これが私たちがtargetdirを前にドラッグして明示的にターゲットとしてマークする必要がある理由です。
これはgnu-findでは機能しますが、他のfind実装では機能しない可能性があります。もちろん、-t-フラグにも依存します。
sh
TechZillaはもちろん、cpを呼び出す必要はないので、一番右にあります。
を使用せず、xargs
ほとんどの場合と組み合わせる必要がない場合は、学習してフラグを立てるfind
必要はありません。-print0
-0
答え4
read -p "SOURCE: " sourcedir
read -p "TYPE: " type
read -p "TARGET: " targetdir
find -L $sourcedir -iname "*.$type" -exec cp -v {} $targetdir \;