今日作成したディレクトリセットを別のディレクトリにコピーするスクリプトを作成しようとしています。
私は現在以下を使用しています:
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はに渡された引数に{}
置き換えられます。したがって、最終的に、、、をパラメータとして呼び出されます。foo
cp
cp
cp
-R
foo
/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つの質問があります。
- 以下を使用して、
%f
主要なディレクトリコンポーネントをファイルとして削除できます。 - 使用中の項目が出力
xargs
で安定して機能しませんfind
(非標準オプションを使用-r
して-0
NULで区切られたレコードを処理することを除く)。
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
。