如何重命名 bash 中的文件以增加名称中的数量?
Posted
技术标签:
【中文标题】如何重命名 bash 中的文件以增加名称中的数量?【英文标题】:How to rename files in bash to increase number in name? 【发布时间】:2019-03-09 11:56:30 【问题描述】:我有几千个文件,命名如下:
Cyprinus_carpio_600_nanopore_trim_reads.fasta
Cyprinus_carpio_700_nanopore_trim_reads.fasta
Cyprinus_carpio_800_nanopore_trim_reads.fasta
Cyprinus_carpio_900_nanopore_trim_reads.fasta
Vibrio_cholerae_3900_nanopore_trim_reads.fasta
对于前两个单词的 80 个变体(80 个不同的物种),我想重命名所有这些文件,使数字增加 100 - 例如:
Vibrio_cholerae_3900_nanopore_trim_reads.fasta
会变成
Vibrio_cholerae_4000_nanopore_trim_reads.fasta
或
Cyprinus_carpio_300_nanopore_trim_reads.fasta
会变成
Cyprinus_carpio_400_nanopore_trim_reads.fasta
不幸的是,我不知道如何重命名它们,我很幸运能够按照https://unix.stackexchange.com/questions/40523/rename-files-by-incrementing-a-number-within-the-filename 上的解决方案进行操作
但我无法让它在名称内部工作,如果有帮助的话,我正在 Ubuntu 18.04 上运行
【问题讨论】:
文件名中是否只有一个数字?或者可能还有更多?它总是第三部分,还是可能在其他地方? 嗨,它总是在同一个位置,而且文件名中只有一个数字,谢谢 【参考方案1】:如果你能得到rename
的Perl 风格版本,那就很简单了:
rename -n 's/(\d+)/$1 + 100/e' *fasta
样本输出
'Ciprianus_maximus_11_fred.fasta' would be renamed to 'Ciprianus_maximus_111_fred.fasta'
'Ciprianus_maximus_300_fred.fasta' would be renamed to 'Ciprianus_maximus_400_fred.fasta'
'Ciprianus_maximus_3900_fred.fasta' would be renamed to 'Ciprianus_maximus_4000_fred.fasta'
如果你看不懂 Perl,那会说... “按如下方式进行一次替换。无论你在哪里看到一串相邻的数字 (\d+
),记住它们 (因为我把它放在括号中),然后用那串数字($1
)加上 100 的计算表达式替换它们。”.
如果试运行看起来正确,请删除-n
。唯一“棘手的部分”是在替换结束时使用e
,这意味着评估替换中的表达式 - 或者我称之为 “计算替换”。
【讨论】:
这看起来不错,我遇到的唯一问题是因为它是增量步骤,所以我得到以下问题:Zygosaccharomyces_rouxii_3000_nanopore_trim_reads.fasta 未重命名:Zygosaccharomyces_rouxii_3100_nanopore_trim_reads.fasta 已经存在 另请注意,有两个常见的可执行文件名为rename
。如果你有util-linux
包提供的那个,你将没有-n
选项。
@DavidC.Rankin 是的,谢谢。这就是为什么我说 “Perl 风味” 的原因!如果您碰巧知道正确的软件包,也许您愿意添加它?再次感谢。
不确定所有文件的实际命名方式。也许你可以给每个加 105,然后减去 5,这样它们就不会发生冲突?在您的文件的备用副本上执行此操作。
@MarkSetchell,不幸的是它依赖于发行版,例如 Archlinux 提供了一个 perl-rename
包,Debian 将它作为 rename
包提供,但 openSuSE 将它捆绑在一些深奥的 perl 包中很明显。最好的建议是rename -h
第一个:)
【参考方案2】:
如果您的字符串中只有一个数字,那么下面两行代码应该可以帮助您解决问题
filename="Vibrio_cholerae_3900_nanopore_trim_reads.fasta"
var=$(echo $filename | grep -oP '\d+')
echo $filename/$var/$((var+100))
您可以将更改的文件名放入变量中并使用mv
命令重命名它,而不是回显更改的文件名
【讨论】:
对于grep
,最好使用+
而不是*
,因为某些版本不使用*
@I'L'l.更新了我的答案【参考方案3】:
考虑到文件名冲突按升序排列,我首先想到的是颠倒顺序,但由于与数字排序的不同,字母(标准)排序仍然存在冲突的可能性。 那么如何分两步解决:在第一步中,在文件名中插入一个转义字符(或任何未出现在文件名中的字符),然后在第二步中将其删除。
#!/bin/bash
esc=$'\033' # ESC character
# 1st pass: increase the number by 100 and insert a ESC before it
for f in *.fasta; do
num=$f//[^0-9]/
num2=$((num + 100))
f2=$f/$num/$esc$num2
mv "$f" "$f2"
done
# 2nd pass: remove the ESC from the filename
for f in *.fasta; do
f2=$f/$esc/
mv "$f" "$f2"
done
【讨论】:
【参考方案4】:Mark 的 perl-rename 解决方案看起来不错,但您应该应用两次,每次增加 50 以避免名称冲突。如果您找不到这种重命名方式,您可以尝试我的 rene.py (https://rene-file-renamer.sourceforge.io),该命令将(也应用两次)rene *_*_*_* *_*_?_* B/50
。 rene 会更容易一些,因为它会自动向您显示更改并询问您是否要进行更改,并且如果您改变主意,它会撤消。
【讨论】:
以上是关于如何重命名 bash 中的文件以增加名称中的数量?的主要内容,如果未能解决你的问题,请参考以下文章