ls 出力の引用に関する問題

ls 出力の引用に関する問題

いくつかのpngファイルをpdfに結合したいのですが、コマンド

convert *png out.pdf

うまく動作しますが、順序が間違っています。

ls -v *png

必要な順序付けが得られるので、その出力を convert に渡します。

私が試してみました

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

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 を 1 つの文字列に結合し、その結果をシェルの入力として使用して、結果のコマンドを実行します。

しかし、問題はeval、コマンドラインのあらゆるものが再度解析され、通常は安全なものでさえも解析されないことです。 というファイルについて考えてみましょう$(touch HELLO)。そのような名前がコマンドラインにドロップされると何が起こるでしょうか。

また、この方法を採用する場合は、--quoting-style=shellの代わりにを使用する-Qと、シェルの特殊文字の処理とより一致する可能性があります。(どちらも GNU ls に固有のものかもしれませんが、私も-vそう思います。)

答え3

を使用するとzsh(n)glob 修飾子によって GNU と同様のソート順序が得られますls -v

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

GNUシステムでは、、、、bashまたは のzsh場合:yashmkshksh93

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

答え4

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

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

関連情報