2010-06-03 81 views
0

我并不十分了解bash脚本或imagemagick,但我正在尝试创建一个脚本,您可以在其中为图像列表提供某种正则表达式匹配模式,然后将它们处理成具有给定文件名前缀的新文件。使用imagemagick通过shell脚本调整图像大小

例如给出下面的目录清单:

allfiles01.jpg allfiles02.jpg allfiles03.jpg

我想调用脚本像这样:

./resisemany.sh allfiles*.jpg 30 newnames*.jpg 

最终的结果是你会得到一堆新名字的新文件,数字相匹配,

到目前为止,我有什么是:

IMAGELIST=$1 
RESIEZFACTOR=$2 
NUMIMGS=length($IMAGELIST) 

for(i=0; i<NUMIMGS; i++) 
    convert $IMAGELIST[i] -filter bessel -resize . RESIZEFACTOR . % myfile.JPG 

感谢您的帮助...... ,我显然需要帮助的是 1.如何给一个bash脚本匹配它理解 2标准的部分。如何使用$ 2而不与图像列表中的第二项匹配 3.如何获取图像列表的长度 4.如何在这种情况下创建适当的循环 5.如何做到正确文本替换为一个shell命令,据此您可以追加到我暗指的项目。

JML

+0

这将无法正常工作。 – 2010-06-03 01:19:08

+0

是否有等效的解决方案? – jml 2010-06-03 01:37:03

回答

4

可能是一个标准程序将工作将采取“在”文件名模式和“出”的文件名模式,在当前目录下的每个文件执行的操作相匹配“的方式“模式,将适当的部分替换为”出“模式。这是很容易的,如果你有一个硬编码的方式,当你可以写一次性的命令,如

for infile in *.jpg; do convert $infile -filter bessel -resize 30% ${infile//allfiles/newnames}; done 

为了使一个脚本,将与任何模式做到这一点,不过,你需要更复杂一些因为你的文件名转换可能比只用另一个替换一个部分更复杂。不幸的是击并没有真正给你一个方法来确定哪些部分文件名匹配的模式的特定部分,所以你必须使用一个更强大的正则表达式引擎,像sed例如:

#!/bin/bash 

inpattern=$1 
factor=$2 
outpattern=$3 
for infile in *; do 
    outfile=$(echo $infile | sed -n "s/$inpattern/$outpattern/p") 
    test -z $outfile && continue 
    convert $infile -filter bessel -resize $factor% $outfile 
done 

可能被援引作为

./resizemany.sh 'allfiles\(.*\).jpg' 30 'newnames\1.jpg' 

(注意单引号!),它会调整到allfiles1.jpgnewnames1.jpg,等于是你会风基本上不必学习sed的正则表达式语法来指定进出模式。 (这并不是说不好,真的)

+0

我不得不说,我宁愿学习awk和sed over perl,因为我在python中为perl所做的大多数事情工作。非常感谢这个解决方案。 – jml 2010-11-02 17:31:14

1

你的脚本应该使用一个语法如被称为:

./resizemany.sh -r 30 -n newnames -o allfiles allfiles*.jpg 

,并使用getopts处理的选项。你可能没有意识到的是,shell在脚本获取之前扩展文件glob,所以你的参数的方式你的脚本将永远无法区分文件名和其他参数。

输出文件将使用经常在安装Perl的系统上找到的rename脚本命名。名为“allfiles03.jpg”的文件将被输出为“newname03.jpg”。

#!/bin/bash 

options=":r:n:o:" 
while getopts $options option 
do 
    case $option in 
     n) 
      newnamepattern=$OPTARG 
      ;; 
     o) 
      oldnamepattern=$OPTARG 
      ;; 
     r) 
      resizefacor=$OPTARG 
      ;; 

     \?) 
      echo "Invalid option" 
      exit 1 
    esac 
done 
# a check to see if any options are missing should be performed (not implemented) 
shift $((OPTIND - 1)) 
# now all that's left will be treated as filenames 
for file 
do 
    convert (input options) "$file" -resize $resizefactor (output options) "${file}.out" 
    rename "s/$old/$new/;s/\.out$//" "${file}.out" 
done 

这是未经测试(显然是因为大多数的参数convert缺失)。

参数验证(如范围检查,缺少必需的选项等)留作练习以供进一步开发。也没有检查成功完成一个步骤,然后继续下一个步骤。还没有解决诸如文件位置和名称冲突等问题。

5

如果你把要处理的所有文件的文件夹,您可以消除正则表达式的问题,然后运行是这样的:

for img in `ls *.jpg` 
do 
    convert $img -filter bessel -resize 30% processed-$img 
done 

然后,如果你需要的所有后来他们重新命名,你可以这样做是这样的:

ls | nl -nrz -w2 | while read a b; do mv "$b" newfilename.$a.jpg; done; 

此外,如果你正在做同样的间歇操作过程中,你可能会看到,如果使用mogrify可能帮助(imagemagik的方法转换多个文件)。就像上面的例子一样,制作一个文件夹的副本总是很好,然后运行任何处理,以免破坏原始文件。