![在 bash 大括号扩展中使用变量](https://linux22.com/image/124632/%E5%9C%A8%20bash%20%E5%A4%A7%E6%8B%AC%E5%8F%B7%E6%89%A9%E5%B1%95%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%8F%98%E9%87%8F.png)
我有一个程序可以生成可变数量的图片,顺序如下:
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