我遇到以下一系列文件的情况:
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
的事情吗?我还想知道是否还有其他简洁的方法(也许是正确的?)来完成此任务。
答案 0 :(得分:1)
好吧,如果所有这些文件都遵循您显示的模式并且位于同一目录中,那么这种单行代码似乎可以正常工作。
$ for d in $( cut -f1-2 -d_ <(ls 1234_*) | sort -u ); do mkdir $d; mv ${d}_* $d; done
此bash命令使用Looping Construct for
,Pipeline |
,Process Substitution <(...)
和Command Substitution {{ 1}}。
$(...)
创建一个与该模式匹配的所有文件的列表。
ls 1234_*
在cut -f1-2 -d_
上分割每个匹配的文件名,然后仅输出前两个字段(包括这两个字段之间的定界符_
)。
_
首先对这些sort -u
前缀进行排序,然后仅输出唯一项。您要使用这些唯一的前缀作为目录名称。
cut
然后在这些唯一的前缀上循环,以创建目录(for
),并mkdir
将前缀匹配的文件添加到该新目录。
谨慎使用并根据需要进行调整。如果此目录中还有其他文件或目录,或者在执行命令时出现错误,则执行或重新执行命令可能无法执行您想要的操作,因为将创建目录,因此glob将不匹配您想要什么,等等。
这是一个例子。
mv