使用可变模式批量重命名 Ubuntu/Linux 中的文件名
Bulk renaming file names in Ubuntu/Linux with variable pattern
我正在努力重命名一堆具有要删除的可变模式的文件。
我有:
1B_ACTCGCTA-CCTAGAGT_L001_R1_001.fastq.gz
1B_ACTCGCTA-CCTAGAGT_L001_R2_001.fastq.gz
97C_TAAGGCGA-TTATGCGA_L001_R1_001.fastq.gz
97C_TAAGGCGA-TTATGCGA_L001_R2_001.fastq.gz
98A_S62_L001_R1_001.fastq.gz
98A_S62_L001_R2_001.fastq.gz
并希望拥有:
1B_R1_001.fastq.gz
1B_R2_001.fastq.gz
97C_R1_001.fastq.gz
97C_R2_001.fastq.gz
98A_R1_001.fastq.gz
98A_R2_001.fastq.gz
如您所见,需要删除的模式是可变的,简单匹配将不起作用。
一个合乎逻辑的解决方法是排除第一个和第三个下划线之间的所有内容,或者排除第一个下划线和字母 "R" 之间的所有内容。
不幸的是,我无法想出可以做到这一点的代码。
它可以是任何东西,只要它能工作,重命名,bash for in loop 等等...
感谢您的帮助,
德尼
编辑:我试图使用 for-loop 但无法想出完整的代码来保留文件名的第二部分(字母 "R" 后面的所有内容)
for file in *.fastq.gz; do echo mv "${file}" "${file/_*/\/}"; done
以下应该有效:
for f in *.fastq.gz; do echo mv "$f" "${f%%_*}_${f#*_*_*_}"; done
我特地在mv
之前添加了echo
,所以它会打印它要移动的东西。如果打印正确,请再次删除 echo
和 运行。
这里发生的是我通过 %% 获取头部并通过 # 获取尾部并将它们连接起来。请参阅 man bash
中的 Parameter Expansion
了解 %% 和 # 的含义。该解决方案依赖于文件名中的 _ 数量不变。
不依赖于下划线数量的答案:
for file in $(ls); do
mv $file $(echo $file | awk -F _ 'BEGIN {OFS="_"} {print , $(NF-1), $NF}');
done
使用 (Perl) rename
:
rename --dry-run 's/_.*_R/_R/' *gz
示例输出
'1B_ACTCGCTA-CCTAGAGT_L001_R1_001.fastq.gz' would be renamed to '1B_R1_001.fastq.gz'
'1B_ACTCGCTA-CCTAGAGT_L001_R2_001.fastq.gz' would be renamed to '1B_R2_001.fastq.gz'
'97C_TAAGGCGA-TTATGCGA_L001_R1_001.fastq.gz' would be renamed to '97C_R1_001.fastq.gz'
'97C_TAAGGCGA-TTATGCGA_L001_R2_001.fastq.gz' would be renamed to '97C_R2_001.fastq.gz'
'98A_S62_L001_R1_001.fastq.gz' would be renamed to '98A_R1_001.fastq.gz'
'98A_S62_L001_R2_001.fastq.gz' would be renamed to '98A_R2_001.fastq.gz'
我正在努力重命名一堆具有要删除的可变模式的文件。
我有:
1B_ACTCGCTA-CCTAGAGT_L001_R1_001.fastq.gz
1B_ACTCGCTA-CCTAGAGT_L001_R2_001.fastq.gz
97C_TAAGGCGA-TTATGCGA_L001_R1_001.fastq.gz
97C_TAAGGCGA-TTATGCGA_L001_R2_001.fastq.gz
98A_S62_L001_R1_001.fastq.gz
98A_S62_L001_R2_001.fastq.gz
并希望拥有:
1B_R1_001.fastq.gz
1B_R2_001.fastq.gz
97C_R1_001.fastq.gz
97C_R2_001.fastq.gz
98A_R1_001.fastq.gz
98A_R2_001.fastq.gz
如您所见,需要删除的模式是可变的,简单匹配将不起作用。 一个合乎逻辑的解决方法是排除第一个和第三个下划线之间的所有内容,或者排除第一个下划线和字母 "R" 之间的所有内容。 不幸的是,我无法想出可以做到这一点的代码。 它可以是任何东西,只要它能工作,重命名,bash for in loop 等等...
感谢您的帮助, 德尼
编辑:我试图使用 for-loop 但无法想出完整的代码来保留文件名的第二部分(字母 "R" 后面的所有内容)
for file in *.fastq.gz; do echo mv "${file}" "${file/_*/\/}"; done
以下应该有效:
for f in *.fastq.gz; do echo mv "$f" "${f%%_*}_${f#*_*_*_}"; done
我特地在mv
之前添加了echo
,所以它会打印它要移动的东西。如果打印正确,请再次删除 echo
和 运行。
这里发生的是我通过 %% 获取头部并通过 # 获取尾部并将它们连接起来。请参阅 man bash
中的 Parameter Expansion
了解 %% 和 # 的含义。该解决方案依赖于文件名中的 _ 数量不变。
不依赖于下划线数量的答案:
for file in $(ls); do
mv $file $(echo $file | awk -F _ 'BEGIN {OFS="_"} {print , $(NF-1), $NF}');
done
使用 (Perl) rename
:
rename --dry-run 's/_.*_R/_R/' *gz
示例输出
'1B_ACTCGCTA-CCTAGAGT_L001_R1_001.fastq.gz' would be renamed to '1B_R1_001.fastq.gz'
'1B_ACTCGCTA-CCTAGAGT_L001_R2_001.fastq.gz' would be renamed to '1B_R2_001.fastq.gz'
'97C_TAAGGCGA-TTATGCGA_L001_R1_001.fastq.gz' would be renamed to '97C_R1_001.fastq.gz'
'97C_TAAGGCGA-TTATGCGA_L001_R2_001.fastq.gz' would be renamed to '97C_R2_001.fastq.gz'
'98A_S62_L001_R1_001.fastq.gz' would be renamed to '98A_R1_001.fastq.gz'
'98A_S62_L001_R2_001.fastq.gz' would be renamed to '98A_R2_001.fastq.gz'