引用 ls 输出时出现问题

引用 ls 输出时出现问题

我想将一些 png 文件合并到 pdf 中。命令

convert *png out.pdf

有效,但顺序错误。事实证明

ls -v *png

给出了我想要的顺序,因此我想将其输出传递给转换。

我努力了

convert `ls -v *png` out.pdf

但这不起作用,因为文件名包含空格和括号。

告诉ls通过双引号设置文件名

convert `ls -vQ *png` out.pdf

也不起作用,因为引号似乎在替换中被删除了。

我能做些什么?

答案1

如果您有一个最新的基于 GNU 的系统(其sort提供了类似的-V自然版本排序),您可以使用它进行排序,并将结果读入数组:

while read -rd '' f; do 
  files+=("$f")
done < <(find . -maxdepth 1 -name '*png' -print0 | sort -zV)

然后您应该能够在convert命令中扩展数组:

convert "${files[@]}" out.pdf

答案2

如果您的文件名中没有任何换行符,您可能只需告诉 shellls仅在换行符上分割输出,默认情况下不分割任何空格即可。这分裂由变量控制IFS,其中包含的任何字符IFS都用作分隔符。

IFS=$'\n'      # set it to just a newline
convert $(ls -vd ./*.png) output.pdf 

如果文件名足够有趣,或者ls破坏了它们的显示,这可能仍然存在问题。打印到终端时,ls通常会在多列中列出文件。但是,当输出没有发送到终端时(此处 shell 读取它),它的行为就像-1已给出一样。


为了实现您开始的想法,您可以使用eval

eval: eval [arg ...]
将 ARG 组合成单个字符串,使用结果作为 shell 的输入,并执行生成的命令。

但问题eval是命令行中的所有内容都会被再次解析,甚至通常安全的东西也不会被解析。想象一个名为 的文件$(touch HELLO),如果在命令行中删除这样的名称会发生​​什么。

另外,如果您采用这种方式,您可能需要使用--quoting-style=shellnot ,-Q因为它可能更匹配 shell 对特殊字符的处理。 (两者都可能特定于 GNU ls,但我认为-v也是如此。)

答案3

使用zshglob(n)限定符可以为您提供与 GNU 类似的排序顺序ls -v

convert ./*.png(n) out.pdf

在 GNU 系统上,使用bashzshyashmkshksh93

eval "files=($(ls --quoting-style=shell-always -vd ./*.png))"
convert "${files[@]}" out.pdf

答案4

使用 GNU Parallel 看起来像这样:

ls -vd ./*png | parallel -Xj1 convert {} out.pdf

相关内容