从现有序列创建新的文件序列以及编号

时间:2012-05-11 06:25:20

标签: bash rename

我知道这个问题已被提出,但我找不到多个解决方案,但它对我不起作用。基本上,我正在寻找一个bash脚本,它将采用如下所示的文件列表:

image1.jpg
image2.jpg
image3.jpg

然后复制每一个,但顺序向后编号。因此,序列将创建三个新文件:

image4.jpg
image5.jpg
image6.jpg

然而,image4.jpg将是image3.jpg的未触及副本,而image5.jpg是image2.jpg的未触及副本,依此类推。我已经尝试了this stackoverflow question中概述的解决方案而没有运气。我承认在bash脚本路径上并不是很远,如果我在第一个列出的答案中获取大量代码并制作脚本,我总是得到“2:语法错误:”(一遍又一遍“意外”。我'尝试改变语法(大约一点,但没有成功。所以,要么我做错了,要么有更好的脚本。

很抱歉没有提前发布,但我正在使用的代码是:

image=( image*.jpg )  
MAX=${#image[*]}  
for i in ${image[*]}  
do  
   num=${i:5:3} # grab the digits  
   compliment=$(printf '%03d' $(echo $MAX-$num | bc))  
   ln $i copy_of_image$compliment.jpg  
done

我正在使用此代码并将其粘贴到nano文件中,然后添加!#/ bin / bash作为第一行,然后chmod +x script并通过sh script在bash中执行。当然,在我的测试运行中,我正在使用名为image1.jpg的文件 - 但我也想知道将这个脚本应用到jpegs目录的方法,不一定标题为图像(整数).jpg - 在我的文件中保持结构,其中大部分是单个单词,后跟一个数字,然后是.jpg,不用为每次使用重写脚本会很好。

2 个答案:

答案 0 :(得分:0)

  • 也许您的真实测试数据从001到300,但是这里有image1 2 3,因此您从文件名中提取一个而不是三个数字。 NUM = $ {I:5:1}

  • 整数算术可以在bash中完成而无需调用bc

  • $ {#image [@]}比$ {#image [*]}更强大,但这里不应该有区别。
  • 我没有查阅字典,但是对你的女朋友不赞美?相反是补充,不是吗? :)
  • 另一个命令发了链接 - 要复制,调用cp。

代码:

#!/bin/bash
image=( image*.jpg )
MAX=${#image[@]}
for i in ${image[@]}
do
    num=${i:5:1}
    complement=$((2*$MAX-$num+1))
    cp $i image$complement.jpg
done 

最重要的是:如果是bash,请使用bash调用它。最好:做一个shebang(就像你做的那样),让它可执行并通过./name调用它。用sh名称调用它将强制使用错误的解释器。如果您不使其可执行,请将其命名为bash name。

答案 1 :(得分:0)

也许是这样的。它适用于像script image*.jpg这样的东西,其中通配符匹配一组文件,这些文件匹配常规模式,具有相同长度的单调增加的数量,而理想情况下与当前目录中较不规则的文件子集匹配。它只是假设最后一个文件的数字索引加上一个文件名总数是要循环的数字范围。

#!/bin/sh

# Extract number from final file name
eval lastidx=\$$#
tmp=${lastidx#*[!0-9][0-9]}
lastidx=${lastidx#${lastidx%[0-9]$tmp}}
tmp=${lastidx%[0-9][!0-9]*}
lastidx=${lastidx%${lastidx#$tmp[0-9]}}

num=$(expr $lastidx + $#)
width=${#lastidx}

for f; do
    pref=${f%%[0-9]*}
    suff=${f##*[0-9]}
    # Maybe show a warning if pref, suff, or width changed since the previous file
    printf "cp '$f' '$pref%0${width}i$suff'\\n" $num
    num=$(expr $num - 1)
done |
sh

这是sh - 兼容;前面的expr内容和子字符串提取是丑陋的,但与Bourne兼容。如果您对Bash的内置算术和字符串操作构造没有问题,那么转换为该表单应该是微不足道的。

(要明确指出,${var%foo}会返回$var的值,foo将结尾修剪,${var#foo}会从值的开头进行类似的修剪。 shell通配符匹配运算符在表达式中可用于修剪内容。${#var}返回值$var的长度。)