根据模式匹配移动文件

根据模式匹配移动文件

我有一些文件的名称如下所示:

XXXXX_S1_X_XX_X.txt
XXXXX_S2_X_XX_X.txt
XXXXX_S3_X_XX_XXX.txt
S4_X_XX_X.txt
XXXXX_S5_XX_X.txt   
...

我创建了一个名为:S1S2S3、 ... 的文件夹列表。我想移动XXXXX_S1_X_XX_X.txt文件夹中的文件、文件夹中的S1文件等等。我写了这个简单的循环,但我不知道如何根据相应文件夹中匹配 S* 的模式复制/移动文件:XXXXX_S2_X_XX_X.txtS2

for i in My_list_of_folders.txt
do 
  dir=${i%.txt}
  mkdir "$dir"
  cp "$i" "$dir"
done

答案1

稍微修改一下的循环:

for pattern in S1 S2 S3 S4; do
   mkdir -p ./"$pattern"
   for filename in ./*"$pattern"*; do
       [ ! -f "$filename" ] && continue
       mv -i "$filename" "$pattern"/
   done
done

这将循环遍历模式字符串S1S2和。内部循环使用当前模式字符串在当前目录中查找包含该字符串的名称。它会跳过非常规文件(例如目录本身等)并将所有其他匹配的内容移动到该模式字符串的适当目录。S3S4S1S2

正如 slm 在评论中指出的那样(现已删除),在这种情况下,内部循环中的操作可以缩短为

[ ! -f "$filename" ] || mv -i "$filename" "$pattern"/

或者

[ -f "$filename" ] && mv -i "$filename" "$pattern"/

如果您有重叠的图案,例如S1S11,那么您需要先制作较长的图案。

答案2

作为备选:

for i in S{4..1};do 
  mkdir -p $i
  while read line; do 
    [ -f "$line" ] && mv "$line" $i
  done < My_list_of_folders.txt
done

怎么运行的:

  • S{4..1}- 使用 shell 扩展来构造目录名称
  • mkdir -p $i- 强制创建目录
  • while read ... < My_list_of_folders.txt- 循环遍历文件中的行
  • [ -f "$line" ]...- 将每个文件移动到相应的 S 目录

笔记:您可以将 glob ({4..1}) 调整为适合您的用例的任何范围。为了处理更大的东西,我们反向排序以处理任何重叠 S20 .... S1,因此是S{20..1}我们的 glob 定义的类型。

相关内容