ファイルにリストされているパターンに一致する特定のディレクトリのみを繰り返しコピーします。

ファイルにリストされているパターンに一致する特定のディレクトリのみを繰り返しコピーします。

次の構造のディレクトリがあります。

-- 201893208
   └── 8Z12
          └── ko_8Z12_Full
          └── wp_we_8Z12_FullDAT
          └── 8Z12_DATFull
   └── P011
          └── P011_Full
          └── 8Z12_FullDAT
          └── P011_DATFull
   └── 9FZA
          └── kl_wt-we-w_kl9-9FZA_Full
          └── ffd-9FZA_FullDAT
          └── 8fdZ12232_9FZA_DATFull
-- 903240920
   └── P0fsa
          └── P0fsa_Full
          └── P0fsa_FullDAT
          └── P0fsa_DATFull
   └── Paaaf
          └── we-Paaaf_ww_fl_Full
          └── Paaaf_FullDAT
          └── Paaaf_DATFull
   └── 9FZATYYY
          └── 9FZATYYY_Full
          └── 9FZATYYY_FullDAT
-- wt0340291
   └── OPF1121
          └── OPF1121_Full
          └── 8Z12_DATFull
   └── KLOFJ9
          └── lop_KLOFJ9_ffj_Full
          └── powt_KLOFJ9_DATFull
   └── LP02323
          └── wr_we_LP02323_Full
          └── wr_we_LP02323_FullDAT

上記の各フォルダには、何千ものファイルがあります。その後、それぞれに多くのサブディレクトリがあります。たとえば、8Z12上記の3つのフォルダだけでなく、何千ものファイルが含まれています。

ただ_Full最後に(のある名前をコピーしたいです。完全なデータ目次コピーしてはいけない)そして以下のリストのパターンが含まれています。

LP02323
KLOFJ9
Paaaf
9FZA

つまり、上記のリストの文字列を含むディレクトリです。そして Fullその名前にコピーする必要があります(DATではありません)。

したがって、上記の例では、次のディレクトリ(およびすべてのコンテンツとサブディレクトリ)のみをコピーする必要があります。

wr_we_LP02323_Full
lop_KLOFJ9_ffj_Full
we-Paaaf_ww_fl_Full
kl_wt-we-w_kl9-9FZA_Full

私が理解したところにrsyncよると、正規表現はサポートされていませんfind。ただし、複数のサブディレクトリに深く埋め込まれている場合でも、すべてのディレクトリとサブディレクトリが確認され、関連するすべてのフォルダがコピーされたことをどのように確認できますか? (上記の例は、元のフォルダ構造の単純化された例です。)

したがって、2つの質問があります。

  • パターンリストをにどのように提供しますかfind
  • findの結果をどのようにパイプしますかrsync

これまで私はこの試合だけを考えることができますFull

find . -regextype sed -regex ".*/.*[^DAT]Full$"

しかし、コマンドにIDリストをどのように追加しますかfind

答え1

ディレクトリ名に現れる必要がある文字列ファイルを使用して、シェルはこれらの文字列を繰り返しますrsync(変数のディレクトリから変数$sourceのディレクトリにコピーするとします$target)。

while IFS= read -r string; do
    rsync --archive --exclude='*DAT*/' --include='*/' --include="*$string*_Full/***" --exclude='*' \
        --prune-empty-dirs "$source"/ "$target"
done <strings.txt

オプションの機能rsync(除外/含むパターンの最初のクリックが重要です):

  • --archive:所有権、権限、タイムスタンプなどをコピーします。
  • --exclude='*DAT*/'DAT:があるすべてのディレクトリを除外します。
  • --include='*/':すべてのディレクトリを考慮します(以前のパターンから除外されたディレクトリを除く)。これは、rsync興味のある物理ディレクトリにアクセスするために必要です。
  • --include="*$string*_Full/***": 指定されたパターンに一致するすべてのディレクトリを考慮します。そしてこのディレクトリのすべて。それなら$stringそれはparrotすべてです--include="*parrot*_Full/***"
  • --exclude='*':まだ明示的に含まれていないことを考慮しないでください。
  • --prune-empty-dirs:コンテンツが明示的に含まれていないディレクトリは送信しないでください。

rsync実行時にスキーマがどのように評価されるかを知りたい場合は、コマンドライン-vvに追加してください。rsync

テスト:

$ tree
.
|-- from
|   `-- a
|       `-- b
|           |-- c_A_DATFull
|           |   `-- file
|           |-- c_A_DAT_Full
|           |   `-- file
|           |-- c_A_Full
|           |   `-- file
|           |-- c_B_DATFull
|           |   `-- file
|           |-- c_B_DAT_Full
|           |   `-- file
|           |-- c_B_Full
|           |   `-- file
|           |-- c_C_DATFull
|           |   `-- file
|           |-- c_C_DAT_Full
|           |   `-- file
|           `-- c_C_Full
|               `-- file
`-- strings.txt

12 directories, 10 files

$ cat strings.txt
A
B

$ source=from
$ target=to

(ここでループを実行してください)

$ tree
.
|-- from
[...]
`-- to
    `-- a
        `-- b
            |-- c_A_Full
            |   `-- file
            `-- c_B_Full
                `-- file

17 directories, 12 files

ワンコールでrsync

set -- --exclude='*DAT*/' --include='*/'
while IFS= read -r string; do
    set -- "$@" --include="*$string*_Full/***"
done <strings.txt
set -- "$@" --exclude='*'

rsync --archive "$@" --prune-empty-dirs "$source"/ "$target"

一方find通行:

set --
while IFS= read -r string; do
    set -- "$@" -o -name "*$string*_Full"
done <strings.txt
shift

# "$@" would now be something like
#    -name *LP02323*_Full -o -name *Paaaf*_Full -o -name ...etc

find "$source" -type d '(' "$@" ')' ! -name '*DAT*' -exec sh -c '
    source=$1; target=$2; shift 2
    for pathname do
        mkdir -p "$target/${pathname#$source}"
        rsync --archive "$pathname"/ "$target/${pathname#$source}"
    done' sh "$source" "$target" {} +

findこれは、コピーしたいサブディレクトリのリストを生成するために使用されます。これには、繰り返される小さなインラインスクリプトが用意されています。

ループが繰り返されるたびに、ターゲットの対応するディレクトリが作成され(ローカルコピーであると仮定)、使用されますrsync

一度もfind使わなかった管路パス名を安全に分離できない場合は、他のコマンドのパス名。

関連:

関連情報