次の構造のディレクトリがあります。
-- 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
使わなかった管路パス名を安全に分離できない場合は、他のコマンドのパス名。
関連: