回答:
GNU mvの場合:
find path_A -name '*AAA*' -exec mv -t path_B {} +
それはfindの-exec
オプションを使用して{}
、それぞれの検索結果を順番に置き換え、指定したコマンドを実行します。で説明されているようにman find
:
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command until
an argument consisting of `;' is encountered.
この場合、できるだけ少ない数の操作を実行するように、+
バージョンを使用しています。-exec
mv
-exec command {} +
This variant of the -exec action runs the specified command on
the selected files, but the command line is built by appending
each selected file name at the end; the total number of invoca‐
tions of the command will be much less than the number of
matched files. The command line is built in much the same way
that xargs builds its command lines. Only one instance of `{}'
is allowed within the command. The command is executed in the
starting directory.
+
は仕事をman find
-exec mv {} path_b +
ていたが、アクセス許可エラーで失敗していました。TBH、私はまだ理由を理解していませんが-exec mv -t path_b {} +
、おやつを機能します!
-exec ... {} +
場合、{}
はの前の最後のものでなければなりません+
。これが彼が使うのmv -t destdir {} +
でなく使う理由mv {} destdir +
です。-exec mv {} destdir ';'
代わりに1つのコールドが使用されていますが、それはmv
各ファイルに対して1回実行されます。
以下のようなこともできます。
find path_A -name "*AAA*" -print0 | xargs -0 -I {} mv {} path_B
どこ、
-0
空白または文字(改行を含む)がある場合、多くのコマンドは機能しません。このオプションは、空白のあるファイル名を処理します。-I
initial-arguments内のreplace-strの出現を、標準入力から読み取られた名前に置き換えます。また、引用符で囲まれていない空白は入力項目を終了しません。代わりに、区切り文字は改行文字です。テスト中
私は2つのディレクトリを作成sourcedir
してdestdir
。今、私の中にたくさんのファイル作成sourcedir
などをfile1.bak
、file2.bak
そしてfile3 with spaces.bak
さて、コマンドを次のように実行しました、
find . -name "*.bak" -print0 | xargs -0 -I {} mv {} /destdir/
今、内部でdestdir
、私が行うときls
、私は、ファイルから移動していることを見ることができましたsourcedir
しdestdir
。
参照資料
http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/
この質問に出くわすOS Xユーザーの利益のために、OS Xの構文はわずかに異なります。次のサブディレクトリを再帰的に検索したくないと仮定しますpath_A
。
find path_A -maxdepth 1 -name "*AAA*" -exec mv {} path_B \;
すべてのファイルを再帰的に検索する場合path_A
:
find path_A -name "*AAA*" -exec mv {} path_B \;
find
私が使用したものと同じです。良い点:(-maxdepth
特にpath_Bがサブディレクトリである場合- mv
既にそこにファイルを移動しようとすることを避けます!)そして\を使用します; (したがって{}は最後のパラメーターである必要はなく、通常のmv
構文を使用できます)
これ-exec
が最善の方法です。何らかの理由でこれがオプションではない場合、ループで結果を読み取ることもできます。
find path_A -name "*AAA*" -print0 |
while IFS= read -r -d $'\0' file; do mv "$file" path_B; done
これは安全な方法です。スペース、改行、またはその他の奇妙な文字を含むファイル名を処理できます。もっと簡単な方法が、1 ファイル名は、単純な英数字のみから構成されていない限り失敗し、あります
mv $(find path_A -name "*AAA*") path_B
ただし、whileループを使用してください。
のみ使用するのPOSIXの機能find
(ともののmv
):
find path_A -name '*AAA*' -exec sh -c 'mv "$@" path_B' find-sh {} +
参考文献:
別の方法
for f in `find path_A -name "*AAA*"`; do mv $f /destination/dir/; done