在 bash 大括号扩展中使用变量

在 bash 大括号扩展中使用变量

我有一个程序可以生成可变数量的图片,顺序如下: 1.jpg, 2.jpg [...] 10.jpg..etc

我不能用作*.jpg输入,因为 10 将在 2、3 等之前处理,所以我想使用:

convert page_{1..$N}.jpg out.pdf

但不起作用。命令应该怎样?

答案1

您可以将文件名存储在数组中,并使用以下命令生成它们seq

pages=( $(printf 'page_%d.jpg\n' $(seq $N)) )
convert "${pages[@]}" out.pdf

答案2

因为执行了大括号扩展变量替换,{1..$n}不会像人们希望的那样工作,并且有避免的充分理由eval。一个简单的解决方案是修复文件名,以便它们按顺序排序。

考虑这些文件:

$ ls
page_10.jpg  page_1.jpg  page_2.jpg  page_3.jpg  page_4.jpg  page_5.jpg  page_6.jpg  page_7.jpg  page_8.jpg  page_9.jpg

通过在单位数文件名前面添加零,我们可以使它们按照您的需要进行排序:

$ for f in ./page_[0-9].jpg; do mv "$f" "./page_0${f#./page_}"; done
$ ls
page_01.jpg  page_02.jpg  page_03.jpg  page_04.jpg  page_05.jpg  page_06.jpg  page_07.jpg  page_08.jpg  page_09.jpg  page_10.jpg

现在您可以使用:

convert *.jpg out.pdf

将 2 位数字转换为 3 位数字

作为斯米特链接指出,上面的内容可以扩展为将 2 位数字转换为 3 位数字:

for f in ./page_[0-9][0-9].jpg; do mv "$f" "./page_0${f#./page_}"; done

作为示例,并使用上面的文件:

$ for f in ./page_[0-9][0-9].jpg; do mv "$f" "./page_0${f#./page_}"; done
$ ls
page_001.jpg  page_002.jpg  page_003.jpg  page_004.jpg  page_005.jpg  page_006.jpg  page_007.jpg  page_008.jpg  page_009.jpg  page_010.jpg

答案3

eval大括号扩展是在变量替换之前执行的,因此如果您想要相反,则需要它:

eval convert page_{1..$N}.jpg out.pdf

另一种方法是对扩展文件名进行排序:

convert $(echo page_*.jpg | tr ' ' '\n' | sort -n -k 2 -t _) out.pdf

相关内容