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

sort同様の自然なソートバージョンを提供する最新のGNUベースのシステムがある場合は、-Vそれを使用してソートして結果を配列として読み取ることができます。

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

convertこれにより、次のコマンドで配列を拡張できます。

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

答え2

ファイル名に改行文字が含まれていない場合は、デフォルトではls空白に分割されていない改行文字にのみ出力を分割するようにシェルに指示できます。これ分ける変数によって制御され、IFSその中に含まれるすべての文字はIFS区切り文字として使用されます。

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

ファイル名が十分に興味深い場合、またはls表示が妨げられている場合は、まだ問題になる可能性があります。端末に印刷すると、lsファイルは通常複数の列に一覧表示されます。ただし、出力が端末(シェルがそれを読む場所)に送信されない場合は、あたかも与えられたかの-1ように動作します。


始めたアイデアを実現するには、できる使用eval

eval:eval [arg ...]
ARGを単一の文字列に結合し、結果をシェルへの入力として使用し、結果コマンドを実行します。

しかし、問題evalは、コマンドラインのすべての項目が再解析され、通常安全な項目も解析されないことです。という名前のファイルを想像してみてください$(touch HELLO)。コマンドラインからその名前を削除するとどうなりますか?

また、このパスを使用している場合は、シェルの特殊文字処理とよりよく一致する可能性があるため、--quoting-style=shellnotを使用することをお勧めします。-Q(どちらもGNU lsに限定されているかもしれませんが、私の考え-vでもそうです。)

答え3

zshglob修飾子を使用すると、(n)GNUと同様のソート順序が提供されますls -v

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

GNUシステムでは、または以下をbash使用します。zshyashmkshksh93

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

答え4

GNU Parallelを使用すると、次のようになります。

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

関連情報