【问题标题】:Rename files sequentially keeping first part of name按顺序重命名文件,保留名称的第一部分
【发布时间】:2017-10-25 11:18:16
【问题描述】:

我有这些文件:

NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.0
NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.1
NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.2
NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.3
NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.4

我想这样重命名:

NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_1.csv
NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_2.csv
NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_3.csv
NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_4.csv
NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_5.csv

我尝试了以下(以及一些变体)但没有成功:

rename -v 's/(NIHMS.+tons).csv.+/\1_[0-9]\.csv/' *.csv*

ls *csv* | sed -E 's/(NIHM.+tons)\.csv.*$/\1_{1..5}.csv/'

ls *csv* | cat -n | while read n f; do mv "$f" "$f_$n.csv"; done

我得到的最接近的是使用给我的最后一个:

1.csv 2.csv 3.csv 4.csv 5.csv

我很确定我可以使用 python 做到这一点,但我正在尝试通过命令行/bash,最好使用正则表达式(我正在努力学习更好)。

【问题讨论】:

  • 这似乎将数字加一,但接受的答案没有。真正想要的行为是什么?
  • @Benjamin W. 我解释了我想要的问题本身,我什至发布了所需输出的示例。我说的最后一件事是举例说明我得到的不是我想要的。
  • 是的,根据问题中所需的输出,编号从 0,1,2,3,4 变为 1,2,3,4,5,但接受的答案直接映射。

标签: regex bash shell command-line rename


【解决方案1】:

使用 sed 创建新名称,保存部分文件名并交换它们:

for file in *.csv.[0-9]*; do
  new_name=$( echo $file | sed 's/\(.*\)\.csv\.\([0-9]*\)/\1_\2.csv/' )
  echo mv $file $new_name
done

为了安全,我把echo放在mv前面。如果结果看起来不错,则取出回波。这是我的结果:

[jack@marta ~]$ for file in *.csv.[0-9]*; do new_name=$(echo $file | sed 's/\(.*\)\.csv\.\([0-9]*\)/\1_\2.csv/'); echo mv $file $new_name; done
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.0 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_0.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.1 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_1.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.10 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_10.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.11 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_11.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.2 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_2.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.3 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_3.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.4 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_4.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.5 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_5.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.6 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_6.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.7 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_7.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.8 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_8.csv
mv NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons.csv.9 NIHMS735398-supplement-Supplemental_Table_-_Top_Down_MS_Identificaitons_9.csv
[jack@marta ~]$ 

【讨论】:

    【解决方案2】:

    一种方法是使用 bash 参数替换:

    for f in *.csv.* ; do d="${f##*.}" ; mv "$f" "${f%*.csv*}__$((d+1)).csv" ; done
    

    d 变量被设置为文件名的最后一位,然后在 mv 中替换它。

    【讨论】:

    • 这里的数字不会增加,是吗?
    • @BenjaminW.: 不,它使用文件名中的那个。
    • 但如果您查看所需的名称,它应该会增加。
    • 输入:0,1,2,3,4;输出:1,2,3,4,5
    • @BenjaminW。 :看来正确的答案是不要增加数字,所以因为没有说清楚所以否决了这个问题。
    【解决方案3】:

    使用 Bash 正则表达式:

    re='(.*)\.csv\.([[:digit:]]+)$'
    for f in *; do
        [[ $f =~ $re ]]
        echo mv "$f" "${BASH_REMATCH[1]}_$(( ${BASH_REMATCH[2]} + 1 )).csv"
    done
    

    当输出看起来正确时,可以删除echo

    如果目标不是增加输入文件编号,而是从 1 开始按顺序编号的文件,则代码可以更改为:

    re='(.*)\.csv\.[[:digit:]]+$'   # Just one capture group
    i=1
    for f in *; do
        [[ $f =~ $re ]]
        echo mv "$f" "${BASH_REMATCH[1]}_$(( i++ )).csv"
    done
    

    现在文件将按字母输入顺序编号为 1、2、3、...。

    【讨论】:

      【解决方案4】:

      未经测试,因为我不在电脑前,但基于您自己对rename 的努力,这应该很接近:

      rename -n '($a,$b)=split /.csv./; $_=$a . ($b+1) . ".csv"' *csv*
      

      split 应将所有内容放在“.csv”之前。进入$a,之后的所有内容都进入$b。第二部分将输出 ($_) 设置为 $a 后跟 $b+1 并附加“.csv”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-10
        • 1970-01-01
        • 1970-01-01
        • 2020-10-20
        • 2015-01-24
        • 2020-08-31
        • 2020-01-29
        相关资源
        最近更新 更多