
我想將一些 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=shell
not ,-Q
因為它可能更符合 shell 對特殊字元的處理。 (兩者都可能特定於 GNU ls,但我認為-v
也是如此。)
答案3
使用zsh
glob(n)
限定符可以為您提供與 GNU 類似的排序順序ls -v
:
convert ./*.png(n) out.pdf
在 GNU 系統上,使用bash
、 zsh
、yash
或mksh
:ksh93
eval "files=($(ls --quoting-style=shell-always -vd ./*.png))"
convert "${files[@]}" out.pdf
答案4
使用 GNU Parallel 看起來像這樣:
ls -vd ./*png | parallel -Xj1 convert {} out.pdf