ファイルを含む数千のフォルダがあり、それらのいくつかを別のディレクトリにコピーしたいと思います。フォルダ名の一部を含む2つの列を持つファイルがあります.csv
(フォルダには1つの文字列値が含まれていますが、両方は含まれません)。
- フォルダ名の例:
PLASMA_32150129_B5/ PLASMA_AAA3891784_B3/ ...
- CSVファイルにはヘッダーがなく、フィールドは次のように区切ります
,
。32150129,AAA0616938 32140203,AAA3891784 32140204,AAA0617237 32140205,AAA0617261 32140206,AAA0617285 ...
- 私はこの小さなスクリプトを出発点として見つけました。
while IFS=, read -r file rest do find /path/to/Main_directory -type d -name "${file}" -exec cp '{}' /path/to/New_directory/ \; done < mylist.csv
今すぐ指定する必要があります。
- csv値は単なるパターン(例えば
*_32150129 _*
)です。 - まず最初の列のパターンを試してみて、一致するものが生成されない場合は別の列を試してみたいと思います。
可能ですか?
ありがとうございます!
答え1
実際には1つの列しか一致できないと仮定すると、「OR」タイプのアプローチが可能になる可能性があります。これを行うには、スクリプトを少し変更するだけです。
while IFS=, read -r pattern1 pattern2
do
find /path/to/start -type d \( -name "*_${pattern1}_*" -o -name "*_${pattern2}_*" \) -exec cp -r '{}' /path/to/target \;
done < filelist.csv
- 演算子は、
-o
2つの名前パターンのうちの1つが一致することを確認します。 2つが一致しない限り(前提条件を参照)、これは「最初が存在しない場合は2番目」と同じです。 - 括弧(シェルの解釈を防ぐためにエスケープ)は、正しい演算子の優先順位を確保するために使用されます。
- シェルパラメータを
-name
二重引用符で囲むと、*
次のことが保証されます。文字通りすぐそこにグローバル拡張は必要なく(find
シェルに渡される前ではなく検索中にパターンマッチングを実行する必要がありますfind
)、シェル変数${pattern1}
と${pattern2}
拡張が引き続き発生することを許可します。 - ディレクトリとその内容をコピーするには、
-r
このオプションを使用する必要があります。cp
答え2
最も簡単で粗雑な方法を試したことがある場合は、効果があります。一つファイルのすべてのパターンを一致させ、シェルに操作を実行させます。
tr , '\n' < mylist.csv |
while read pat; do cp -r source_dir/*"$pat"* target_dir/ 2>/dev/null; done
まず、すべてを改行,
に変換しますfile.csv
。
$ tr , '\n' < file.csv
32150129
AAA0616938
32140203
AAA3891784
32140204
AAA0617237
32140205
AAA0617261
32140206
AAA0617285
次に、各パターンを変数として読み込み(つまり、マッチのすべての項目)、ターゲットディレクトリに盲目的に$pat
コピーします。一致するものがないと、何もコピーされず、エラーメッセージが表示され、これにDiscardを使用できます。source_dir/*$pat*
source_dir/
$pat
2>/dev/null
より複雑なアプローチのためには、次のようにすることができます。
## make sure we don't match the glob pattern itself when no matching
## directories are found
shopt -s nullglob
mainTargetDir=/path/to/Main_directory
sourceDir=/path/to/start
while IFS=, read -r f1 f2; do
sourceFiles=("$sourceDir"/*"$f1"* "$sourceDir"/*"$f2"*)
[ -z "${sourceFiles[@]}" ] ||
cp -r -- "${sourceFiles[@]}" $mainTargetDir
done < file.csv