搜索包含 CSV 文件中列出的模式的文件夹并将其复制到另一个位置

搜索包含 CSV 文件中列出的模式的文件夹并将其复制到另一个位置

我有数千个文件夹,其中包含文件,我想将其中一些复制到另一个目录中。我有一个.csv包含两列的文件,其中包含文件夹名称的一部分(该文件夹包含一个字符串值或另一个字符串值,而不是两者都包含)。

  • 文件夹名称示例:
    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

假设只有一列可以实际匹配,“或”类型的方法可能是可能的。为此,只需对脚本进行少量修改:

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将确保两个名称模式中的任何一个生成匹配。只要两者不能匹配(请参阅先决条件),这将相当于“如果第一个不存在,则第二个”
  • 括号(转义以防止 shell 解释)用于确保正确的运算符优先级。
  • 将 shell 参数放在-name双引号中将确保*保留从字面上看就在那里无需进行全局扩展(这是必要的,以便find在搜索期间执行模式匹配,而不是在将其传递给之前的外壳find),同时仍然允许外壳变量${pattern1}${pattern2}进行扩展。
  • 如果您想要复制目录及其内容,则必须使用-r选项。cp

答案2

最简单、最粗暴的方法,如果你曾经有过,应该会起作用匹配文件中的每个模式,就是让 shell 完成工作:

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,然后盲目地将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 

相关内容