BASH内からcpを呼び出し、-uオプションを使用する

BASH内からcpを呼び出し、-uオプションを使用する

ソース ディレクトリに新しいバージョンのファイルが含まれていたためにコピーされなかったファイルを のオプションで印刷するcp方法はありますか?--update

答え1

cp -urと置換するrsync -urvv

2 つの「v」はタイプミスではありません。スキップされたファイルを表示するために、詳細度を上げるためにあります。

スキップされたファイルは のようになりますthe_filename is newer。スキップされたファイルのリストを取得するには、次のワンライナーを使用できます。

rsync -urvv source/ target | grep ' is newer$' | sed -e 's/ is newer$//'

または、対話型で使用する場合、--progressフラグは非常に役立ちます。

答え2

これを直接行う方法はないと思いますcpが、基本的には同じことを行うはずです:

cp -vu file destination | awk '{ gsub("[`\x27]", "", $1); print $1 } END { if (NR == 0) print "NOFILES" }' | xargs -I{} find . ! -name {} -maxdepth 1

この短いワンライナーにはいくつかの制限があります:

1) 「NOFILES」という名前のファイルが存在しないことが条件です。 コマンド内の文字列は、awk必要に応じて変更できます。

2) が存在するディレクトリにいる必要がありますfile。そのディレクトリにいない場合は、findコマンドを のfind dirWhereFileExists代わりに に変更する必要があります。find . 単一のディレクトリからコピーしていない場合は、代わりに を使用できますfind dir1 dir2...

3) 何らかの理由でファイル名にバッククォートまたは一重引用符が含まれている場合は機能しません。

ご存知のとおり、これは最も堅牢なソリューションではありませんが、1 回限りの操作であれば十分でしょう。

編集

今朝目が覚めて、上記の解決策が役に立たないことに気付きました。複数のファイルをコピーしようとすると、ファイルの数だけ検索され、そのたびに 1 つのファイルが除外されます。ただし、次の解決策は機能するはずです。

cp -vu file destination | awk '{ gsub("[`\x27]", "", $1); regex = $1 "|" regex } END { if (NR == 0) { regex = "NOFILES|" } print ".*/("substr(regex, 0, length(regex))")" }' | xargs -I{} find . -regextype posix-extended ! -regex {} -maxdepth 1

実行時に正規表現を構築し、find代わりに に渡します。上記と同じ制限が適用されます。

先ほどは思いつきですみません。StackOverflow に載るには遅すぎたようです。

答え3

rsync はあなたのために役立ちますか? 「新しいファイルを上書きしない」など、あなたの説明に合う多くのオプションがあります。また、検出結果をログに記録することもできます。私はリモート ファイルとローカル ファイルのコピーに rsync をよく使用します。

非常に細かく設定することもできます。

幸運を。

関連情報