Rsyncおよびcpコマンドは、「.txt」ファイルを単一のディレクトリにコピーします(すでに存在する場合のみ)。

Rsyncおよびcpコマンドは、「.txt」ファイルを単一のディレクトリにコピーします(すでに存在する場合のみ)。

複数のディレクトリに複数のファイルを含むディレクトリ構造があります.txt.txtこれらすべてのファイルを特定のディレクトリにコピーしたいと思います。以下に私のディレクトリ構造を指定しました。

Dir_1
    a.txt
    x.doc
    b.txt
Dir_2
    c.txt
Dir_3
    d.txt
    e.txt
    y.doc

.txtすべてのファイルをディレクトリにコピーするには、~/alltxt次のcpコマンドを使用します。

find . -name "*.txt" -exec cp {}  ~/alltxt/  \;

それは非常にうまく動作します。今私のディレクトリはalltxt次のようになります。

alltxt
        a.txt
        b.txt
        c.txt
        d.txt
        e.txt

.txtしかし、変更されたファイルだけがそのフォルダに置き換えたいと思いました。そのためrsync、次のコマンドを使用すると、これを行うことができることがわかりました。

find .  -name '*.txt' -exec rsync -R {} ~/alltxt/ \;

.txt ただし、以下のようにフォルダごとにファイルをコピーします。

alltxt
  Dir_1
    a.txt
    x.doc
    b.txt
  Dir_2
    c.txt
  Dir_3
    d.txt
    e.txt
    y.doc

rsyncしかし、私のコマンドのように動作するようにコマンドをどのように変更できますかcp

ベストアンサー1

rsync--existingターゲットにまだ存在しないファイルをコピーしないフラグがあります。

find . -type f -name '*.txt' -exec rsync --existing {} "$HOME/alltxt/" ';'

-type fまた、次の項目のみを検索findするように追加しました。一般ファイル、この場合には有用ではないと思うので-Rフラグ( --relative) を削除しました(このフラグを使用するとターゲットにサブディレクトリが生じる理由でもあります)。rsync私もそれが良く見えると思うので、$HOME代わりに使用します。~

所有権や変更時間などを保存するために、呼び出しに-a--archive)を追加することもできます。rsync

同様の方法ですが、cp代わりに使用されますrsync

find . -type f -name '*.txt' \
    -exec sh -c 'for n; do d="$HOME/alltxt/${n##*/}"; [ -f "$d" ] && cp "$n" "$d"; done' sh {} +

これはすべての.txtファイルを見つけ、短いシェルスクリプトを呼び出します。

for n; do
    d="$HOME/alltxt/${n##*/}"
    [ -f "$d" ] && cp "$n" "$d"
done

このループはここから多くの.txtファイルをインポートしますfind。これらの名前ごとにn宛先ファイルパスを作成し、dそのパスが既存の一般ファイルを参照していることを確認し、その場合は指定されたファイルをそこにコピーします。

ターゲットファイルが存在し、見つかったファイルより古い場合は、[ -f "$d" ]代わりにこのテストを使用できます。[ "$d" -ot "$n" ]これは非標準テストですが、ほとんどのシェルでサポートされています。

変数置換はパス${n##*/}からディレクトリを削除することによって(basename)にnなります。で置き換えることができます。./some/path/file.txtfile.txt$(basename "$n")

おすすめ記事