Bash 解析文件名并按特定顺序重命名

Bash 解析文件名并按特定顺序重命名,bash,parsing,rename,Bash,Parsing,Rename,我在一个目录中有许多tiff文件,必须重命名,但它们有数百个,因此很麻烦。文件如下所示: basefilename_0002_-0.0.mrc basefilename_0003_3.0.mrc basefilename_0004_-3.0.mrc basefilename_0005_-6.0.mrc basefilename_0006_6.0.mrc etc... 我需要做的就是更改文件名的中间部分,以便将前41个.mrc文件更改为: basefilename_0001_-0.0.mrc

我在一个目录中有许多
tiff
文件,必须重命名,但它们有数百个,因此很麻烦。文件如下所示:

basefilename_0002_-0.0.mrc
basefilename_0003_3.0.mrc
basefilename_0004_-3.0.mrc
basefilename_0005_-6.0.mrc 
basefilename_0006_6.0.mrc 
etc...
我需要做的就是更改文件名的中间部分,以便将前41个
.mrc
文件更改为:

basefilename_0001_-0.0.mrc
basefilename_0001_3.0.mrc
basefilename_0001_-3.0.mrc
basefilename_0001_-6.0.mrc 
basefilename_0001_6.0.mrc 
etc.
第二批
.mrc
文件:

basefilename_0043_-0.0.mrc
basefilename_0044_3.0.mrc
basefilename_0045_-3.0.mrc
basefilename_0046_-6.0.mrc
basefilename_0047_6.0.mrc
将重命名为

basefilename_0002_-0.0.mrc
basefilename_0002_3.0.mrc
basefilename_0002_-3.0.mrc
basefilename_0002_-6.0.mrc 
basefilename_0002_6.0.mrc 
etc.

因此,本质上我必须在
“basefilename”
之后和下一个
之前进行解析并重命名,以便数字不是升序而是0001。但是我有数百个这样的脚本,我需要确保每个41
mrc
文件在
basefile
名称之后和下一个描述之前都是相同的数字。

我确信有比下面的shell脚本更好的方法来获得您想要的,但是下面的类似方法应该可以工作,假设文件按需要排序:

#!/bin/bash

set -e

count=1
index=1

for p in *.mrc; do
    if expr $count == 42 > /dev/null; then
        index=`expr $index + 1`
        count=1
    else
        count=`expr $count + 1`
    fi

    mv $p `echo $p | sed -e "s/\(.*_\)\([0-9]*\)\(_.*\)/\1000${index}\3/"`
done
上面的
sed
命令将文件名
$p
分成三个部分,分别位于转义括号对之间,
\(…\)

  • 保留在
    \1
    中的基本文件名(例如
    foo
  • 正在修改的中心数字替换为
    000${index}
    ,其中
    ${index}
    对于第一组41个文件扩展为
    1
    ,对于第二组文件扩展为
    2
    ,等等,以及
  • 保留在
    \3
这不是一个非常健壮的实现,因为如果
$index
大于
9
,您可能会得到像
00023
这样的中心数字,但我认为您已经了解了自己的实现


您还可以使用Bash字符串操作内置程序,而不是
sed
。请参见中的。

您可以使用bash本身提供的本机工具实际执行所需操作,而无需依赖任何需要生成单独子shell的单独实用程序。Bash提供了带有子字符串替换的参数扩展,您可以使用子字符串替换
之间的文本(
0001
,…)

Bash还提供了
printf-vvar
,它允许您在
var
中保存格式化输出的同时,具有
man3print
的所有格式化灵活性。因此,例如,如果我有一个值
1
,我想将其格式化为
0001
,并存储在变量
blkno
,那么这是一个简单的
printf-v“%04d”1'

将其与一个简单计数器相结合,然后使用bash提供的
运算符,您可以使用以下各项执行所需操作:

#!/bin/bash

ext=${1:-mrc}                           ## extension of files to select
declare -i blksz=${2:-41} cnt=0 blk=1   ## files per-block, counters
printf -v blkno "%04d" $blk             ## format 1st blk as 0001

for i in *.$ext; do                     ## loop over each file with extension
    ## test output showing what would be moved, to new name
    printf "mv %-28s %s\n" "$i" "${i/_*_/_${blkno}_}"
    ## mv "$i" "${i/_*_/_${blkno}_}"    ## (uncomment for actual move)
    (((cnt+1) % blksz == 0)) && {       ## check if blksz output
        ((blk++))                       ## increment blk number
        printf -v blkno "%04d" $blk     ## format as 4-digit w/leading zeros
    }
    ((cnt++))                           ## increment count
done
请注意,脚本的第一个参数是要循环的文件的扩展名(默认值为
.mrc
),以及默认情况下每个块中包含的文件数
41

示例输入文件

我没有你的确切文件,所以我生成了类似的循环和
touch
,例如

basefilename_0002_-0.0.mrc
basefilename_0003_3.0.mrc
basefilename_0004_-3.0.mrc
basefilename_0005_6.0.mrc
basefilename_0006_-6.0.mrc
basefilename_0007_9.0.mrc
basefilename_0008_-9.0.mrc
basefilename_0009_12.0.mrc
basefilename_0010_-12.0.mrc
basefilename_0011_15.0.mrc
basefilename_0012_-15.0.mrc
basefilename_0013_18.0.mrc
basefilename_0014_-18.0.mrc
basefilename_0015_21.0.mrc
basefilename_0016_-21.0.mrc
basefilename_0017_24.0.mrc
basefilename_0018_-24.0.mrc
basefilename_0019_27.0.mrc
basefilename_0020_-27.0.mrc
basefilename_0021_30.0.mrc
basefilename_0022_-30.0.mrc
basefilename_0023_33.0.mrc
basefilename_0024_-33.0.mrc
basefilename_0025_36.0.mrc
basefilename_0026_-36.0.mrc
basefilename_0027_39.0.mrc
basefilename_0028_-39.0.mrc
basefilename_0029_42.0.mrc
basefilename_0030_-42.0.mrc
basefilename_0031_45.0.mrc
basefilename_0032_-45.0.mrc
basefilename_0033_48.0.mrc
basefilename_0034_-48.0.mrc
basefilename_0035_51.0.mrc
basefilename_0036_-51.0.mrc
basefilename_0037_54.0.mrc
basefilename_0038_-54.0.mrc
basefilename_0039_57.0.mrc
basefilename_0040_-57.0.mrc
basefilename_0041_60.0.mrc
basefilename_0042_-60.0.mrc
basefilename_0043_0.0.mrc
basefilename_0044_-0.0.mrc
basefilename_0045_3.0.mrc
basefilename_0046_-3.0.mrc
basefilename_0047_6.0.mrc
basefilename_0048_-6.0.mrc
basefilename_0049_9.0.mrc
basefilename_0050_-9.0.mrc
basefilename_0051_12.0.mrc
basefilename_0052_-12.0.mrc
basefilename_0053_15.0.mrc
basefilename_0054_-15.0.mrc
basefilename_0055_18.0.mrc
basefilename_0056_-18.0.mrc
basefilename_0057_21.0.mrc
basefilename_0058_-21.0.mrc
basefilename_0059_24.0.mrc
basefilename_0060_-24.0.mrc
basefilename_0061_27.0.mrc
basefilename_0062_-27.0.mrc
basefilename_0063_30.0.mrc
basefilename_0064_-30.0.mrc
basefilename_0065_33.0.mrc
basefilename_0066_-33.0.mrc
basefilename_0067_36.0.mrc
basefilename_0068_-36.0.mrc
basefilename_0069_39.0.mrc
basefilename_0070_-39.0.mrc
basefilename_0071_42.0.mrc
basefilename_0072_-42.0.mrc
basefilename_0073_45.0.mrc
basefilename_0074_-45.0.mrc
basefilename_0075_48.0.mrc
basefilename_0076_-48.0.mrc
basefilename_0077_51.0.mrc
basefilename_0078_-51.0.mrc
basefilename_0079_54.0.mrc
basefilename_0080_-54.0.mrc
basefilename_0081_57.0.mrc
basefilename_0082_-57.0.mrc
basefilename_0083_60.0.mrc
basefilename_0084_-60.0.mrc
basefilename_0085_0.0.mrc
basefilename_0086_-0.0.mrc
basefilename_0087_3.0.mrc
basefilename_0088_-3.0.mrc
basefilename_0089_6.0.mrc
basefilename_0090_-6.0.mrc
basefilename_0091_9.0.mrc
basefilename_0092_-9.0.mrc
basefilename_0093_12.0.mrc
basefilename_0094_-12.0.mrc
basefilename_0095_15.0.mrc
basefilename_0096_-15.0.mrc
basefilename_0097_18.0.mrc
basefilename_0098_-18.0.mrc
basefilename_0099_21.0.mrc
basefilename_0100_-21.0.mrc
示例使用/输出

注意:实际移动
mv
行被注释掉,允许您在执行实际移动之前测试脚本并根据需要进行调整。如果您对以
mv开头的行的性能感到满意,请取消对该行的注释

脚本将输出已移动的文件、文件的原始文件名和新文件名,例如

mv basefilename_0002_-0.0.mrc   basefilename_0001_-0.0.mrc
mv basefilename_0003_3.0.mrc    basefilename_0001_3.0.mrc
mv basefilename_0004_-3.0.mrc   basefilename_0001_-3.0.mrc
mv basefilename_0005_6.0.mrc    basefilename_0001_6.0.mrc
mv basefilename_0006_-6.0.mrc   basefilename_0001_-6.0.mrc
mv basefilename_0007_9.0.mrc    basefilename_0001_9.0.mrc
mv basefilename_0008_-9.0.mrc   basefilename_0001_-9.0.mrc
mv basefilename_0009_12.0.mrc   basefilename_0001_12.0.mrc
mv basefilename_0010_-12.0.mrc  basefilename_0001_-12.0.mrc
mv basefilename_0011_15.0.mrc   basefilename_0001_15.0.mrc
mv basefilename_0012_-15.0.mrc  basefilename_0001_-15.0.mrc
mv basefilename_0013_18.0.mrc   basefilename_0001_18.0.mrc
mv basefilename_0014_-18.0.mrc  basefilename_0001_-18.0.mrc
mv basefilename_0015_21.0.mrc   basefilename_0001_21.0.mrc
mv basefilename_0016_-21.0.mrc  basefilename_0001_-21.0.mrc
mv basefilename_0017_24.0.mrc   basefilename_0001_24.0.mrc
mv basefilename_0018_-24.0.mrc  basefilename_0001_-24.0.mrc
mv basefilename_0019_27.0.mrc   basefilename_0001_27.0.mrc
mv basefilename_0020_-27.0.mrc  basefilename_0001_-27.0.mrc
mv basefilename_0021_30.0.mrc   basefilename_0001_30.0.mrc
mv basefilename_0022_-30.0.mrc  basefilename_0001_-30.0.mrc
mv basefilename_0023_33.0.mrc   basefilename_0001_33.0.mrc
mv basefilename_0024_-33.0.mrc  basefilename_0001_-33.0.mrc
mv basefilename_0025_36.0.mrc   basefilename_0001_36.0.mrc
mv basefilename_0026_-36.0.mrc  basefilename_0001_-36.0.mrc
mv basefilename_0027_39.0.mrc   basefilename_0001_39.0.mrc
mv basefilename_0028_-39.0.mrc  basefilename_0001_-39.0.mrc
mv basefilename_0029_42.0.mrc   basefilename_0001_42.0.mrc
mv basefilename_0030_-42.0.mrc  basefilename_0001_-42.0.mrc
mv basefilename_0031_45.0.mrc   basefilename_0001_45.0.mrc
mv basefilename_0032_-45.0.mrc  basefilename_0001_-45.0.mrc
mv basefilename_0033_48.0.mrc   basefilename_0001_48.0.mrc
mv basefilename_0034_-48.0.mrc  basefilename_0001_-48.0.mrc
mv basefilename_0035_51.0.mrc   basefilename_0001_51.0.mrc
mv basefilename_0036_-51.0.mrc  basefilename_0001_-51.0.mrc
mv basefilename_0037_54.0.mrc   basefilename_0001_54.0.mrc
mv basefilename_0038_-54.0.mrc  basefilename_0001_-54.0.mrc
mv basefilename_0039_57.0.mrc   basefilename_0001_57.0.mrc
mv basefilename_0040_-57.0.mrc  basefilename_0001_-57.0.mrc
mv basefilename_0041_60.0.mrc   basefilename_0001_60.0.mrc
mv basefilename_0042_-60.0.mrc  basefilename_0001_-60.0.mrc
mv basefilename_0043_0.0.mrc    basefilename_0002_0.0.mrc
mv basefilename_0044_-0.0.mrc   basefilename_0002_-0.0.mrc
mv basefilename_0045_3.0.mrc    basefilename_0002_3.0.mrc
mv basefilename_0046_-3.0.mrc   basefilename_0002_-3.0.mrc
mv basefilename_0047_6.0.mrc    basefilename_0002_6.0.mrc
mv basefilename_0048_-6.0.mrc   basefilename_0002_-6.0.mrc
mv basefilename_0049_9.0.mrc    basefilename_0002_9.0.mrc
mv basefilename_0050_-9.0.mrc   basefilename_0002_-9.0.mrc
mv basefilename_0051_12.0.mrc   basefilename_0002_12.0.mrc
mv basefilename_0052_-12.0.mrc  basefilename_0002_-12.0.mrc
mv basefilename_0053_15.0.mrc   basefilename_0002_15.0.mrc
mv basefilename_0054_-15.0.mrc  basefilename_0002_-15.0.mrc
mv basefilename_0055_18.0.mrc   basefilename_0002_18.0.mrc
mv basefilename_0056_-18.0.mrc  basefilename_0002_-18.0.mrc
mv basefilename_0057_21.0.mrc   basefilename_0002_21.0.mrc
mv basefilename_0058_-21.0.mrc  basefilename_0002_-21.0.mrc
mv basefilename_0059_24.0.mrc   basefilename_0002_24.0.mrc
mv basefilename_0060_-24.0.mrc  basefilename_0002_-24.0.mrc
mv basefilename_0061_27.0.mrc   basefilename_0002_27.0.mrc
mv basefilename_0062_-27.0.mrc  basefilename_0002_-27.0.mrc
mv basefilename_0063_30.0.mrc   basefilename_0002_30.0.mrc
mv basefilename_0064_-30.0.mrc  basefilename_0002_-30.0.mrc
mv basefilename_0065_33.0.mrc   basefilename_0002_33.0.mrc
mv basefilename_0066_-33.0.mrc  basefilename_0002_-33.0.mrc
mv basefilename_0067_36.0.mrc   basefilename_0002_36.0.mrc
mv basefilename_0068_-36.0.mrc  basefilename_0002_-36.0.mrc
mv basefilename_0069_39.0.mrc   basefilename_0002_39.0.mrc
mv basefilename_0070_-39.0.mrc  basefilename_0002_-39.0.mrc
mv basefilename_0071_42.0.mrc   basefilename_0002_42.0.mrc
mv basefilename_0072_-42.0.mrc  basefilename_0002_-42.0.mrc
mv basefilename_0073_45.0.mrc   basefilename_0002_45.0.mrc
mv basefilename_0074_-45.0.mrc  basefilename_0002_-45.0.mrc
mv basefilename_0075_48.0.mrc   basefilename_0002_48.0.mrc
mv basefilename_0076_-48.0.mrc  basefilename_0002_-48.0.mrc
mv basefilename_0077_51.0.mrc   basefilename_0002_51.0.mrc
mv basefilename_0078_-51.0.mrc  basefilename_0002_-51.0.mrc
mv basefilename_0079_54.0.mrc   basefilename_0002_54.0.mrc
mv basefilename_0080_-54.0.mrc  basefilename_0002_-54.0.mrc
mv basefilename_0081_57.0.mrc   basefilename_0002_57.0.mrc
mv basefilename_0082_-57.0.mrc  basefilename_0002_-57.0.mrc
mv basefilename_0083_60.0.mrc   basefilename_0002_60.0.mrc
mv basefilename_0084_-60.0.mrc  basefilename_0003_-60.0.mrc
mv basefilename_0085_0.0.mrc    basefilename_0003_0.0.mrc
mv basefilename_0086_-0.0.mrc   basefilename_0003_-0.0.mrc
mv basefilename_0087_3.0.mrc    basefilename_0003_3.0.mrc
mv basefilename_0088_-3.0.mrc   basefilename_0003_-3.0.mrc
mv basefilename_0089_6.0.mrc    basefilename_0003_6.0.mrc
mv basefilename_0090_-6.0.mrc   basefilename_0003_-6.0.mrc
mv basefilename_0091_9.0.mrc    basefilename_0003_9.0.mrc
mv basefilename_0092_-9.0.mrc   basefilename_0003_-9.0.mrc
mv basefilename_0093_12.0.mrc   basefilename_0003_12.0.mrc
mv basefilename_0094_-12.0.mrc  basefilename_0003_-12.0.mrc
mv basefilename_0095_15.0.mrc   basefilename_0003_15.0.mrc
mv basefilename_0096_-15.0.mrc  basefilename_0003_-15.0.mrc
mv basefilename_0097_18.0.mrc   basefilename_0003_18.0.mrc
mv basefilename_0098_-18.0.mrc  basefilename_0003_-18.0.mrc
mv basefilename_0099_21.0.mrc   basefilename_0003_21.0.mrc
mv basefilename_0100_-21.0.mrc  basefilename_0003_-21.0.mrc

请仔细查看,如果您还有其他问题,请告诉我。

您正在寻找shell脚本吗?如果是,在哪个站台?是的。在linux上,那么也许是bash脚本?您的想法是正确的,您可以从我的回答中获得
printf-v
技巧,以消除可能的
00023
问题。最后一个注意事项是尽可能避免在bash中使用循环调用实用程序(例如
sed
)。如果有1000个文件,那就是1000次调用
sed
(和1000个单独的子shell)。这将使您的脚本更加高效。@DavidC.Rankin非常好。你的方法比我的好得多。我也学到了一些新东西。谢谢+1这正是我需要的!在实际重命名之前,测试也非常有用。是的,这总是一个很大的优点。始终编写一个测试用例,只输出脚本将要执行的操作(在实际执行之前)。这将允许你验证它是否符合你的意愿——并在你需要调整某些东西时为你免去无尽的悲痛。。。祝你的脚本编写顺利。我正在回顾脚本。我正在努力更好地理解剧本。脚本的这部分做什么:%-28s%s\n。另外,假设我不想替换“-*”中的数字,我只想将0001放在.mrc文件扩展名之前的00020003数字之前。如何修改脚本?这只是一个字段宽度修饰符,
'-'
使字段左对齐。因此,由于文件名是~28个字符,我希望它们都是28个字符(并且左对齐),因此右列的格式很好。
%-28s%s\n
只是示例输出的完整
printf
格式字符串。除了输出将要执行的操作外,它对脚本没有任何其他影响。有关完整的详细信息,请参阅系统上的
man 3 printf
。如果您希望使用
basefilename\u0.0\u 0001.mrc
而不是
basefilename\u 0001\u0.0.mrc
,这是可行的,但需要多个附加步骤,因为它不再是单个替换,而是对名称的各个部分进行完整的重新格式化。