根据文件和文件夹名称的正则表达式匹配将文件复制到文件夹中

时间:2019-07-18 22:09:15

标签: regex bash shell unix mv

我遇到以下一系列文件的情况:

1234_A_data1_v1.ext
1234_A_data1_v2.ext
1234_A_data2_v1.ext
1234_A_data2_v2.ext
1234_B_data1_v1.ext
1234_B_data1_v2.ext
1234_B_data2_v1.ext
1234_B_data2_v2.ext
1234_AA_data1_v1.ext
1234_AA_data1_v2.ext
1234_AA_data2_v1.ext
1234_AA_data2_v2.ext
1234_BB_data1_v1.ext
1234_BB_data1_v2.ext
1234_BB_data2_v1.ext
1234_BB_data2_v2.ext

正则表达式字符串1234_[A-Z]+标识数据集。我想为每个这样的数据集创建文件夹(基于文件名),然后将相应的文件移动到所述文件夹中。例如,将1234_A_data1_v1.ext,1234_A_data1_v2.ext,1234_A_data2_v1.ext,1234_A_data2_v2.ext放在文件夹1234_A下。

我设法如下创建文件夹:

grep -o -E '^[0-9]+_[A-Z]+' seqnames | xargs echo | xargs mkdir

哪个给了我

1234_A
1234_A_data1_v1.ext
1234_A_data1_v2.ext
1234_A_data2_v1.ext
1234_A_data2_v2.ext
1234_B
1234_B_data1_v1.ext
1234_B_data1_v2.ext
1234_B_data2_v1.ext
1234_B_data2_v2.ext
1234_AA
1234_AA_data1_v1.ext
1234_AA_data1_v2.ext
1234_AA_data2_v1.ext
1234_AA_data2_v2.ext
1234_BB
1234_BB_data1_v1.ext
1234_BB_data1_v2.ext
1234_BB_data2_v1.ext
1234_BB_data2_v2.ext

这一切都很好。但是现在,我不知道如何将文件移动到各自的文件夹中,我很迷茫。

任何有关如何实现此目标的指标将不胜感激。

尤其是,有什么方法可以做类似mv *<pattern>*filename *<pattern>*destination的事情吗?我还想知道是否还有其他简洁的方法(也许是正确的?)来完成此任务。

1 个答案:

答案 0 :(得分:1)

好吧,如果所有这些文件都遵循您显示的模式并且位于同一目录中,那么这种单行代码似乎可以正常工作。

$ for d in $( cut -f1-2 -d_ <(ls 1234_*) | sort -u ); do mkdir $d; mv ${d}_* $d; done

此bash命令使用Looping Construct forPipeline |Process Substitution <(...)Command Substitution {{ 1}}。

$(...)创建一个与该模式匹配的所有文件的列表。 ls 1234_*cut -f1-2 -d_上分割每个匹配的文件名,然后仅输出前两个字段(包括这两个字段之间的定界符_)。 _首先对这些sort -u前缀进行排序,然后仅输出唯一项。您要使用这些唯一的前缀作为目录名称。 cut然后在这些唯一的前缀上循环,以创建目录(for),并mkdir将前缀匹配的文件添加到该新目录。

谨慎使用并根据需要进行调整。如果此目录中还有其他文件或目录,或者在执行命令时出现错误,则执行或重新执行命令可能无法执行您想要的操作,因为将创建目录,因此glob将不匹配您想要什么,等等。

这是一个例子。

mv