変更されたディレクトリツリーでファイルを「検索して置換する」 Bash コマンド

変更されたディレクトリツリーでファイルを「検索して置換する」 Bash コマンド

私のサーバーの中央リポジトリに研究用ファイルのコレクションを構築しました。私は常にリポジトリを管理し、ディレクトリの名前を変更して移動し、ディレクトリのツリー構造を変更します。私はリポジトリ内のファイルのローカルコピーを常に更新して編集しています。これにより、リポジトリにクライアントの新しいファイルに置き換える必要があるファイルがありますが、ディレクトリツリーが変更される状況が発生します。

rsyncまだ学んでいないオプションはありますか?ディレクトリツリーを変更すると、rsyncが機能しないことがわかりました。私はテストしましたrsync --existing

それとも少しありますか?コマンドライン-fu使用findしてmvWebなどを検索してみてください。リソース検索のみを検索して置き換えるファイルにはい。

- アップデート1可能であれば、@meuhと@Lqueryvgに素晴らしい答えを提供します。 @css1971が彼の答えに追加され、ファイル管理を転覆させる強力なケースを作成したことを確認しました。残念ながら、時間が足りなくなり、報酬システムが私のお気に入りの答えを選びました。私はすべての答えが非常に有益であることがわかりました。みんなに感謝したいです。次の週末に、より思慮深い意見を提示できることを楽しみにしています。

ベストアンサー1

[私のコメントからOPに拡張]。flatすべてのファイルのコピーを含みますが、単純なリストにあるリポジトリにディレクトリを作成します。コピーはハードリンクなので、スペースを取らないでください。ローカルコンピュータでも同じことをしてください。その後、ローカルフラットディレクトリからリモートフラットディレクトリにrsyncできます。 rsyncを使用すると、リモートハードリンクが保存されるため、すべてのリモートファイルが更新されます--inplace。フラットディレクトリはrsyncの前にスクリプトとして作成され、rsyncの後に削除できます。

以下は、実行可能な概念証明テストスクリプトです。

#!/bin/bash
dosync(){  # function to create flat trees and rsync them
    mkdir flat
    mkdir flatl
    find repo  -type f -exec ln {} flat \;
    find local -type f -exec ln {} flatl \;
    rsync -aHv --inplace flatl/ flat
    rm -fr flat flatl
}

# create repo and local dirs with same content. 3 empty files
cd /tmp || exit
mkdir repo
( cd repo; touch a b c )
mkdir local
rsync -a repo/ local

dosync
echo hi >local/a   # example change of local file a
dosync
mkdir repo/new     # example move of repo file b
mv repo/b repo/new/
echo hello >local/b  # change local file b
dosync

ls -lR repo local
# rm -fr flat flatl repo local

反対方向の場合、dosyncがローカル修正をリポジトリに転送した後、単にrm -fr local「rsync -a repo / local」を使用してリポジトリ全体をローカルファイルシステムにコピーできます。代わりに、同様の技術を使用してリポジトリに転送する必要がある新しいファイルの数を減らすことができます。

reversesync(){
    mkdir flat
    mkdir flatl
    find repo  -type f -exec ln {} flat \;
    find local -type f -exec ln {} flatl \;
    mv flat repo/flat
    mv flatl local/flat # not flatl!
    rsync -aHv --delete repo/ local
    rm -fr repo/flat local/flat
}

これにより、rsyncがハードリンクされたファイルを表示してコピーを回避できるように、フラット化されたツリーはそれぞれストレージとローカルディレクトリに移動されます。 (明らかに今回はフラットディレクトリの名前は同じでなければなりません)。


既知のファイルが変更されている場合は、リポジトリでfindそれを使用してツリーから新しい場所を取得し、そこからファイルを同期できます。たとえば、

file=mychangedfile.abc
to=$(find repo -name "$file")
from=$(find local -name "$file")
rsync -av "$from" "$to"

これはリポジトリがインストールされていると仮定しますssh repo find...。そうでなければ、リポジトリでsshを使用できない場合は、rsyncを使用して仮想ローカルターゲットにファイルのリストを取得し、目的のファイルを抽出できます。

to=$(rsync -a --list-only repo dummy | awk '/\/'"$file"'$/{print $NF}')

おすすめ記事