/home
フォルダーの下には、次のような多くのサブフォルダーがあります。
/home/user1
/home/user2/user_sub_2
/home/user3/user_sub_3/info_sub
/home/user4/INFO_FOLDER
/home
の下にあるすべてのファイルを再帰的に/tmp/calculation
フォルダーにコピーします。すべてのファイルは、ターゲットフォルダに直接配置する必要があります(サブディレクトリは作成しないでください)。 2つ以上のファイルが同じ名前の場合、最後に変更されたファイルを/tmp/calculation
にコピーする必要があります。
このアクションを実行するための正しいアプローチは何ですか?
find /home ! -type d -exec bash -c '
for pathname do
if [ "$pathname" -nt "/tmp/calculation/${pathname##*/}" ]
then
cp "$pathname" /tmp/calculation
fi
done' bash {} +
これにより、/home
の下にあるすべての非ディレクトリファイルが検索され、これらのバッチの場合、短いbash
スクリプトが呼び出されます。
短いbash
スクリプトは、パス名の現在のバッチをループし、それぞれについて-nt
テストを使用して、現在のファイルがターゲットディレクトリ内のコピーよりも新しいかどうか(またはコピーがそこに存在しないかどうか)をテストします。ターゲットディレクトリ内のファイルが古い場合、またはファイルが存在しない場合は、cp
を使用して現在のファイルをターゲットディレクトリにコピーします。
パラメータ展開${pathname##*/}
は、実際のファイル名の前にあるディレクトリパスを削除し、パス名のファイル名部分のみを残します。 $(basename "$pathname")
に置き換えることができます。
関連:
ほとんど無関係:
-nt
テストは非標準のテストです。これが、bash
が呼び出す内部スクリプトにfind
を使用することを選択した理由です。 sh -c
の代わりにbash -c
を使用すると、おそらくが機能しますが、テストのセマンティクスは、sh
になりすますシェル間でわずかに異なる場合があります。
たとえば、bash
、zsh
、およびksh
シェルでは、最初のオペランドに2番目のオペランドよりも新しい変更タイムスタンプがある場合、-nt
テストはtrueになります。または、第2オペランドが存在しない場合。
ただし、dash
シェルでは、両方のファイルがほとんど存在し、テストを行うには、最初のファイルが2番目のファイルよりも新しい必要があります。 true(ドキュメントによる)。この場合、この違いは問題になりませんでした。
yash
シェルでは、どちらかのファイルが存在しない場合に何が起こるかはマニュアルで指定されていません。
したがって、非標準の機能を使用する場合は、特定のシェルを使用するのが最も安全です。この特定の場合、おそらくがsh -c
で機能したとしてもです。とにかく。
(このインスタンスでbash
を使用した場合のdownsideは、比較するタイムスタンプの解像度が1秒しかないことですが、それは別の話)
以下のコマンドで試してみましたが、うまくいきました
for file in `find /home -type f | awk -F "/" '{print $NF}'`
do
for dir in `find . -type d| sed "s/\.//g"| sed 's/$/\//g'`
do
Sudo find $dir -type f -iname $file | awk '{print "ls -ltrh" " " $0}'
done | sh | sed -n '$p'
done | awk '{print "cp -rvfp" " " $NF " " "/destinationlocationtocopy/"}' | sh