
いくつかの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
場合: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