xargsを使用したディレクトリのコピー

xargsを使用したディレクトリのコピー

今日作成したディレクトリセットを別のディレクトリにコピーするスクリプトを作成しようとしています。

私は現在以下を使用しています:

find /test/downloads/ -mindepth 1 -maxdepth 1 -type d -mtime -1 -printf '%f\n' | xargs -I '{}' cp -R '{}' /test/uploads/

しかし、これによりエラーが発生しました。

cp: cannot stat 'foo': No such file or directory

私は何を見逃していますか?

答え1

-printf '%f\n'現在のファイルパスの終わりと改行文字を印刷するGNU拡張。ファイルパスがある場合は/test/downloads/foo印刷しますfoo\n

xargsこの出力を取得します。これには、with(引用符、改行文字(唯一の区切り文字)、および先行スペース、EOF文字)として特別に扱われる文字はfoo含まれません。xargs-I{}-I

Soはに渡された引数に{}置き換えられます。したがって、最終的に、、、をパラメータとして呼び出されます。foocpcpcp-Rfoo/test/uploads/

cpしたがって、検索は.dllではなく現在の作業ディレクトリで行われます。foo/test/downloads

ファイルがすでに呼び出されている場合、/test/downloads/-t..コマンドは次のようになります。

cp -R -t.. /test/uploads/

現在の作業ディレクトリの親ディレクトリにcpコピーするように指示します。/test/uploads/

ファイル名がある場合は/test/downloads/ 'blah'<newline>"blah"2cp回呼び出されますcp -R blah /test/uploads/

したがって、2つの質問があります。

  1. 以下を使用して、%f主要なディレクトリコンポーネントをファイルとして削除できます。
  2. 使用中の項目が出力xargsで安定して機能しませんfind(非標準オプションを使用-rして-0NULで区切られたレコードを処理することを除く)。

cpまた、一度に複数のファイルをコピーできますが、cp各ディレクトリを呼び出すと付け加えることもできます。

ここで、標準は次のようにする必要があります。

find /test/downloads/. ! -name . -prune -type d -mtime -1 -exec sh -c '
  exec cp -R "$@" /test/uploads/' sh {} +

これらのユーティリティ(デフォルトではDebianシステムで見つかります)のGNU実装を使用すると、次のように単純化できます。

find /test/downloads/ -mindepth 1 -maxdepth 1 -type d -mtime -1 \
  -exec cp -Rt /test/uploads/ {} +

答え2

""というファイルがある可能性がありますfoo bar

より良いアプローチは、-printf ...最初から最後まで次に置き換えることです。

-print0 | xargs -0 -r cp -t /Test/Uploads

読むman find xargs cp

関連情報