引用 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

相關內容