【问题标题】:append filenames matching with sequential numbers附加与序号匹配的文件名
【发布时间】:2019-02-07 00:11:17
【问题描述】:

我正在尝试通过将序号添加到具有匹配文件名的文件来添加/修改文件名。我仍在学习,但基于 SO 的一些帖子,我已经能够接近。问题是下面的代码按顺序向所有文件添加数字,而不是基于匹配的文件名。

e='t'
j=1
basename="$1"
newname="$2"
for f in "$basename"*.run?.t
do
    echo mv -- "$f" "$newname${f#$basename%.run*.t}.run$((j++)).$e"
done

这是我的文件的简化版本:

1234.Gorilla_sub1.run1.t
1234.Gorilla_sub2.run1.t
1234.Gorilla_sub3.run1.t
1234.Gorilla_sub1.run2.t
1234.Gorilla_sub2.run2.t

4578.Gorilla_sub1.run1.t
4578.Gorilla_sub2.run1.t

我想要:

1234.Gorilla_sub1.run1.t
1234.Gorilla_sub2.run2.t
1234.Gorilla_sub3.run3.t
1234.Gorilla_sub1.run4.t
1234.Gorilla_sub2.run5.t

4578.Gorilla_sub1.run1.t
4578.Gorilla_sub2.run2.t

但我上面的代码是这样做的:

1234.Gorilla_sub1.run1.t.run1.t
1234.Gorilla_sub2.run1.t.run2.t
1234.Gorilla_sub3.run1.t.run3.t
1234.Gorilla_sub1.run1.t.run4.t
1234.Gorilla_sub2.run1.t.run5.t

4578.Gorilla_sub1.run1.t.run6.t
4578.Gorilla_sub2.run2.t.run7.t

如何让它根据相同的文件名前缀(1234.Gorilla、4578.Gorilla)重新开始编号?还要替换 run?.t 而不是添加它?文件读取子的部分?我稍后会删除,如果这有影响的话。 非常感谢!

【问题讨论】:

  • 您的问题不清楚。请缩进您的代码并提供更好的输入示例
  • 您输入的样本是重复文件...您希望它们以“.t”结尾?用“.1”?还是首先存在的任何东西?您上面的代码无法给出您所说的输出。
  • 抱歉,我修改了示例以更好地匹配我的文件。
  • 需要保留订单吗?
  • 不,我想我是否理解正确。

标签: bash rename string-matching sequential


【解决方案1】:

假设顺序很重要,看看这个可爱且可读性强的代码:

#!/usr/bin/env bash   

declare -A a
shopt -s extglob nullglob

reg='_sub([0-9]+).run([0-9]+).t$'

for f in *_sub+([0-9]).run+([0-9]).t; do
    [[ $f =~ $reg ]] && printf '%d %d %s\0' "${BASH_REMATCH[@]:1}" "$f"
done | sort -zn -k2,2 -k1,1 | cut -zd' ' -f3- |
while IFS= read -rd '' f; do
    echo mv -- "$f" "${f%.*.t}.run$((++a[${f%_*}])).t"
done

测试运行:

mv -- 1234.Gorilla_sub1.run1.t 1234.Gorilla_sub1.run1.t
mv -- 4578.Gorilla_sub1.run1.t 4578.Gorilla_sub1.run1.t
mv -- 1234.Gorilla_sub2.run1.t 1234.Gorilla_sub2.run2.t
mv -- 4578.Gorilla_sub2.run1.t 4578.Gorilla_sub2.run2.t
mv -- 1234.Gorilla_sub3.run1.t 1234.Gorilla_sub3.run3.t
mv -- 1234.Gorilla_sub1.run2.t 1234.Gorilla_sub1.run4.t
mv -- 1234.Gorilla_sub2.run2.t 1234.Gorilla_sub2.run5.t

如果您对结果满意,请删除echo

【讨论】:

    【解决方案2】:

    那么,你应该在达到 2 后重新设置 j。 使用您的代码:

    e='t'
    j=1
    basename="$1"
    newname="$2"
    for f in "$basename"*.run?.t
    do
        echo mv -- "$f" "$newname${f#$basename%.run*.t}.run$((j++)).$e"
        if (( j == 2 )); then 
            $(( j = 1 )); 
        fi;
    done
    

    【讨论】:

    • 感谢您的回复。实际上,每个唯一的基本名称都会有多达数百个文件。
    猜你喜欢
    • 2015-03-10
    • 2019-04-14
    • 2011-03-19
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多