22

ファイルパスの配列を渡して、xargsそれらすべてを新しい場所に移動しようとしています。私のスクリプトは現在次のように動作しています:

FILES=( /path/to/files/*identifier* )
if [ -f ${FILES[0]} ]
  then
    mv ${FILES[@]} /path/to/destination
fi

FILES を配列として持つ理由はif [ -f /path/to/files/*identifier* ]、ワイルドカード検索が複数のファイルを返す場合に失敗するためです。ファイルが存在する場合は移動が実行されるため、最初のファイルのみがチェックされます。

各ファイルを移動するためにmv ${FILES[@]} /path/to/destination渡す行に置き換えたいと思います。単一の をオーバーロードするのに十分なファイルがあると予想されるため、使用する必要があります。調査を通じて、ファイルを再度検索することを既に知っているファイルを移動する方法しか見つけることができませんでした。${FILES[@]}xargsxargsmv

#Method 1
ls /path/to/files/*identifier* | xargs -i mv '{}' /path/to/destination

#Method 2
find /path/to/files/*identifier* | xargs -i mv '{}' /path/to/destination

既存の配列内のすべての要素をに渡す方法はあり${FILES[@]}ますxargsか?

以下は、私が試した方法とそのエラーです。

試行 1 :

echo ${FILES[@]} | xargs -i mv '{}' /path/to/destination

エラー:

mv: cannot stat `/path/to/files/file1.zip /path/to/files/file2.zip /path/to/files/file3.zip /path/to/files/file4.zip': No such file or directory

試行 2 :xargs直接実行できるかどうかわかりませんでした。

xargs -i mv ${FILES[@]} /path/to/destination

エラー: エラー メッセージは出力されませんでしたが、手動で停止するまで、その行の後でハングしました。

編集:作品を探す

以下を試したところ、すべてのファイルが移動しました。これが最善の方法ですか?また、ファイルを1つずつ移動しているので、端末が過負荷になりませんか?

find ${FILES[@]} | xargs -i mv '{}' /path/to/destination

編集2:

今後の参考のために、受け入れられた回答方法と、最初の編集で使用した方法をテストしましたtime()。両方の方法を 4 回実行した後、私の方法の平均は 0.659 秒で、受け入れられた答えは 0.667 秒でした。したがって、どちらの方法も他の方法よりも速く動作しません。

4

1 に答える 1

46

あなたがするとき

echo ${FILES[@]} | xargs -i mv '{}' /path/to/destination

xargs は、行全体を単一の引数として扱います。配列の各要素を新しい行に分割し、xargs期待どおりに動作する必要があります。

printf "%s\n" "${FILES[@]}" | xargs -i mv '{}' /path/to/destination

または、ファイル名に改行を含めることができる場合は、次のことができます

printf "%s\0" "${FILES[@]}" | xargs -0 -i mv '{}' /path/to/destination
于 2013-10-18T15:48:17.077 に答える