moo*_*eep 34 bash filenames wildcards
我在一个目录中有这个 pdf 文件列表:
c0.pdf c12.pdf c15.pdf c18.pdf c20.pdf c4.pdf c7.pdf
c10.pdf c13.pdf c16.pdf c19.pdf c2.pdf c5.pdf c8.pdf
c11.pdf c14.pdf c17.pdf c1.pdf c3.pdf c6.pdf c9.pdf
Run Code Online (Sandbox Code Playgroud)
我想按数字顺序使用 ghostscript 连接这些(类似于此):
gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=out.pdf *.pdf
Run Code Online (Sandbox Code Playgroud)
但是 shell 扩展顺序不会重现数字的自然顺序,而是按字母顺序:
$ for f in *.pdf; do echo $f; done
c0.pdf
c10.pdf
c11.pdf
c12.pdf
c13.pdf
c14.pdf
c15.pdf
c16.pdf
c17.pdf
c18.pdf
c19.pdf
c1.pdf
c20.pdf
c2.pdf
c3.pdf
c4.pdf
c5.pdf
c6.pdf
c7.pdf
c8.pdf
c9.pdf
Run Code Online (Sandbox Code Playgroud)
如何在扩展中实现所需的顺序(如果可能,无需手动将0-padding添加到文件名中的数字)?
我找到了使用建议ls | sort -V,但我无法让它适用于我的特定用例。
Tho*_*hor 17
根据您的环境,您可以使用ls -vGNU coreutils,例如:
gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
-sOutputFile=out.pdf $(ls -v)
Run Code Online (Sandbox Code Playgroud)
或者,如果您使用的是最新版本的 FreeBSD 或 OpenBSD:
gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
-sOutputFile=out.pdf $(ls | sort -V)
Run Code Online (Sandbox Code Playgroud)
G-M*_*ca' 15
如果所有有问题的文件都具有相同的前缀(即数字之前的文本;c在这种情况下),您可以使用
gs ...args... c?.pdf c??.pdf
c?.pdf扩展到c0.pdf c1.pdf…… c9.pdf。
c??.pdf扩展到c10.pdf c11.pdf... c20.pdf
(并且最多扩展到c99.pdf,如适用)。虽然每个包含路径名扩展字符的命令行单词都被扩展为根据LC_COLLATE变量排序(整理)的文件名列表,但不会合并由相邻通配符(globs)扩展产生的列表;它们只是连接在一起。(我似乎记得 shell 手册页曾经明确说明了这一点,但我现在找不到了。)
当然,如果文件可以达到c999.pdf,你应该使用c?.pdf c??.pdf c???.pdf. 诚然,如果您有很多数字,这会变得乏味。你可以稍微缩写一下;例如,对于(最多?至)五位数字,您可以使用c?{,?{,?{,?{,?}}}}.pdf. 如果您的文件名列表很少(例如,有 ac0.pdf和 a c12345.pdf,但不一定是中间的每个数字),您可能应该设置该nullglob选项。否则,如果(例如)你没有两位数字的文件,你会得到一个c??.pdf传递给你的程序的文字参数。
如果您有多个前缀(例如,,
和,带有一位或两位数字),您可以使用明显的蛮力方法:a<number>.pdfb<number>.pdf c<number>.pdf
a?.pdf a??.pdf b?.pdf b??.pdf c?.pdf c??.pdf
Run Code Online (Sandbox Code Playgroud)
或将其折叠为{a,b,c}?{,?}.pdf.
如果没有差距,以下内容可能会有所帮助(尽管在边缘情况和一般性方面粗略且不稳健)——只是为了得到一个想法:
FILES="c0.pdf"
for i in $(seq 1 20); do FILES="${FILES} c${i}.pdf"; done
gs [...args...] $FILES
Run Code Online (Sandbox Code Playgroud)
如果可能有差距,[ -f c${i}.pdf ]可以添加一些检查。
编辑也看到这个答案,根据它你可以(使用 Bash)使用
gs [..args..] c{1..20}.pdf
Run Code Online (Sandbox Code Playgroud)