rsync のフィルター オプションを使用することをお勧めします。あなたの例では、次のように入力してください:
rsync -vam -f'+ *[Nn][Aa][Mm][E]*' -f'+ */' -f'- *' a b
最初のフィルタ ルールは、rsync にどのパターンを含めるかを指示します。 2 番目のルールは、トラバーサルですべてのディレクトリを検査するように rsync に指示するために必要です。空のディレクトリが含まれないようにするために、それらは -m
によって明示的に除外されます オプション。最後のフィルタ ルールは、まだ一致していない残りのすべてのパターンを破棄するように rsync に指示します。
rsync は正規表現を話しません。少し難解ですが、find と grep を使用できます。目的のファイルを見つけるには:
find a/ |
grep -i 'name'
しかし、それらはすべて "a/" という接頭辞が付いています - これは理にかなっていますが、最終的には、rsync に受け入れられるインクルード パターンのリストを作成したいと考えています。切り取りで削除します:
find . |
grep -i 'name' |
cut -d / -f 2-
まだ問題があります。rsync は除外リスト内のディレクトリを検索しないため、サブディレクトリ内のファイルを見逃すことになります。 awk を使用して、一致するファイルのサブディレクトリをインクルード パターンのリストに追加します。
find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}'
あとは、リストを rsync に送信するだけです。引数 --include-from=- を使用して、標準入力で rsync にパターンのリストを提供できます。つまり、まとめ:
find a/ |
grep -i 'name' |
cut -d / -f 2- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/
ソース ディレクトリ「a」は、「a/」と「./a/」という 2 つの異なるパスを介して参照されることに注意してください。これは地味ですが重要です。一貫性を保つために、最後に 1 つの変更を行い、常にソース ディレクトリを "./a/" として参照します。ただし、これは、検索結果の前に余分な「./」があるため、カット コマンドを変更する必要があることを意味します:
find ./a/ |
grep -i 'name' |
cut -d / -f 3- |
awk -F/ '{print; while(/\//) {sub("/[^/]*$", ""); print}}' |
rsync -avvz --include-from=- --exclude='*' ./a/ ./b/
ZSH を使用する場合は、(#i) フラグを使用して大文字と小文字の区別をオフにすることができます。例:
$ touch NAME
$ ls (#i)*name*
NAME
ZSH は除外もサポートします。除外は通常のパスと同じように指定されますが、最初に ~
$ touch aa ab ac
$ ls *~*c
aa ab
除外を連鎖させることができます:
$ ls *~*c~*b
aa
最後に、返されるファイルの種類 (ディレクトリ、ファイルなど) を指定できます。これは、ディレクトリの場合は (/)、ファイルの場合は (.) で行われます。
$ touch file
$ mkdir dir
$ ls *(.)
file
これらすべてに基づいて、私はそのコマンドを次のように実行します:
rsync -avvz *(/) (#i)*name* ./a/ ./b/
(これらのセレクターを除外する必要はないと思います)