批量重命名长文件名

时间:2016-12-05 21:55:22

标签: linux rename filenames

我的文件名如下:

5_END_1033_ACAGTG_L002_R1_001.fastq.gz
5_END_1033_ACAGTG_L002_R2_001.fastq.gz
40_END_251_GTGAAA_L002_R1_001.fastq.gz
40_END_251_GTGAAA_L002_R2_001.fastq.gz

我想要类似的东西:

END_1033_R1.fastq.gz
END_1033_R2.fastq.gz
END_251_R1.fastq.gz
END_251_R2.fastq.gz

有没有很好的方法在linux中重命名这些文件?

1 个答案:

答案 0 :(得分:2)

您可以尝试使用循环来提取文件名的重要部分:

for file in ./*.gz; do newname=$(echo $file | sed -re 's/^([^ACAGTG]+).*(R[1-3]).*/\1\2\.fastq\.gz/g'); echo $newname; done

这只会给你一个新的文件名列表。然后你可以移动它们:

for file in ./*.gz; do newname=$(echo $file | sed -re 's/^([^ACAGTG]+).*(R[1-3]).*/\1\2\.fastq\.gz/g'); mv $file $newname; done

稍微打破一下:

  • 遍历* .gz文件
  • 创建一个从名称中删除不必要内容的变量
  • 将文件名移至新名称

我希望有更好的方法可以做到这一点,但这是我想到的最重要的事情。

测试:

$ ls
40_END_251_GTGAAA_L002_R1_001.fastq.gz  40_END_251_GTGAAA_L002_R2_001.fastq.gz  5_END_1033_ACAGTG_L002_R1_001.fastq.gz  5_END_1033_ACAGTG_L002_R2_001.fastq.gz

$ for file in ./*.gz; do newname=$(echo $file | sed -re 's/^([^ACAGTG]+).*(R[1-3]).*/\1\2\.fastq\.gz/g'); echo $newname; done
./40_END_251_R1.fastq.gz
./40_END_251_R2.fastq.gz
./5_END_1033_R1.fastq.gz
./5_END_1033_R2.fastq.gz

$ for file in ./*.gz; do newname=$(echo $file | sed -re 's/^([^ACAGTG]+).*(R[1-3]).*/\1\2\.fastq\.gz/g'); mv $file $newname; done

$ ls
40_END_251_R1.fastq.gz  40_END_251_R2.fastq.gz  5_END_1033_R1.fastq.gz  5_END_1033_R2.fastq.gz

注意我在bash 4.4.5中执行此操作

修改 鉴于我并不完全确定名称中哪些列最重要,awk可能效果更好:

for file in ./*.gz; do newname=$(echo $file | awk -F'_' '{print $2 "_" $3 "_" $6}' -); echo $newname; done

这会将文件名拆分为_,并允许您使用$X引用所需的列:

for file in ./*.gz; do newname=$(echo $file | awk -F'_' '{print $2 "_" $3 "_" $6}' -); mv $file "${newname}.fastq.gz"; done