フォルダとサブフォルダのファイルを再帰的にコピーするには?

フォルダとサブフォルダのファイルを再帰的にコピーするには?

フォルダの下には、次のようないくつかの/homeサブフォルダがあります。

/home/user1
/home/user2/user_sub_2
/home/user3/user_sub_3/info_sub
/home/user4/INFO_FOLDER

/home以下のすべてのファイルを再帰的にコピーしようとしています/tmp/calculation。すべてのファイルはターゲットフォルダに直接配置する必要があります(サブディレクトリを作成しないでください)。複数のファイルが同じ名前を持っている場合は、最後に変更されたファイルをにコピーする必要があります/tmp/calculation

これを行う正しい方法は何ですか?

答え1

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内部スクリプトを選択しましたfindsh -c代わりに使用bash -c可能働いたしかし、テストの意味は、として偽装することができるシェルによってわずかに異なる場合がありますsh

たとえば、シェルのbash最初のオペランドの修正タイムスタンプが2番目のオペランドの修正タイムスタンプよりも最新の場合、または2番目のオペランドが存在しない場合、テストは真です。zshksh-nt

しかし、dashシェルでは両方ファイルはほとんど存在し、文書によると、テストを維持するには、最初のファイルが2番目のファイルより最新である必要があります。この場合、この違いは問題になりません。

yashシェルでは、マニュアルは、2つのファイルが存在しない場合に何が起こるかを指定しません。

したがって、非標準機能を使用する場合は、特定のシェルを使用するのが最も安全です。おそらくsh -cとにかくすでに一緒に働いています。

(これ欠点この例で使用されているのは、bash比較されるタイムスタンプで1秒の解像度しかないことです。しかし、これは別の話です。)

答え2

次のコマンドを試してみましたが、うまくいきます。

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

関連情報