如何重命名 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 中的文件以增加名称中的数量?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 bash 脚本重命名当前目录及其子目录中的文件?

.bat 用于批量重命名以增加 fname 中的数字

用于递归重命名文件夹的 Bash 脚本

根据 Bash 中的模式更改目录名称

sh 重命名文件夹中的文件以匹配文件夹名称(对于htpc用法很有用)

重命名 BASH 中的几个文件