bash:ファイル名を含む複数のスペースを渡す

bash:ファイル名を含む複数のスペースを渡す

Bashスクリプトでは、PDFをページ単位でラスタライズして単一のファイルにし、結果の単一のPNGを次のようにPDFにマージします。

convert -monitor /path/to/1.png /path/to/2.png /path/to/3.png ... output.pdf

スクリプトがまだ持っている唯一の問題は、空白のファイルを正しく処理できないことです。私が試したいくつかのことは次のとおりです。

newfile=$(sed -r -e 's| |\\ |g' <<< "$tmppath$curr.png")
echo "DEBUG: newfiles : $newfiles"
filearray[$curr-1]="$newfiles"
echo "DEBUG: filearray: ${filearray[*]}"

これにより、(ページ/ファイルあたり)以下が生成されます。

DEBUG: newfiles : /tmp/pngpdf/file\ with\ spaces/1.png
DEBUG: filearray: /tmp/pngpdf/file\ with\ spaces/1.png

後で2つのデバッグメッセージが表示されます。

echo "DEBUG: filearray: ${filearray[*]}"
echo "DEBUG:            ${filearray[0]}, ${filearray[1]}, ${filearray[2]}, ..."

filearray複数のファイル/ページがどのように見えるかを確認してください。

DEBUG: filearray: /tmp/pngpdf/file\ with\ spaces/1.png /tmp/pngpdf/file\ with\ spaces/2.png /tmp/pngpdf/file\ with\ spaces/3.png /tmp/pngpdf/file\ with\ spaces/4.png /tmp/pngpdf/file\ with\ spaces/5.png
DEBUG:            /tmp/pngpdf/file\ with\ spaces/1.png, /tmp/pngpdf/file\ with\ spaces/2.png, /tmp/pngpdf/file\ with\ spaces/3.png, ...

以下をはっきりと見ることができます。

  1. 各ファイルには配列要素が1つしかありません。
  2. 各空白の前にはが付きます\

まず、コマンド全体を変数に入れ、その機能が何であるかを確認します。

execcmd="convert -monitor ${filearray[@]} output.pdf"

例は次のとおりです。

convert -monitor /tmp/pngpdf/file\ with\ spaces/1.png /tmp/pngpdf/file\ with\ spaces/2.png /tmp/pngpdf/file\ with\ spaces/3.png /tmp/pngpdf/file\ with\ spaces/4.png /tmp/pngpdf/file\ with\ spaces/5.png output.pdf

しかし、$execcmdConvertを使用して実行すると、多くのエラーが発生します。

convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/1.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/1.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/2.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/2.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/3.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/3.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/4.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/4.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/5.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/5.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: no images defined `output.pdf' @ error/convert.c/ConvertImageCommand/3044.

どうやら私がやりたいことを正しく認識していないようです。バックスラッシュ自体がエスケープされるので、スペースは引数区分機能を再取得します。このコマンドを bash に直接入力すると、期待どおりにスムーズに実行されます。

$ convert -monitor /tmp/pngpdf/file\ with\ spaces/1.png /tmp/pngpdf/file\ with\ spaces/2.png /tmp/pngpdf/file\ with\ spaces/3.png /tmp/pngpdf/file\ with\ spaces/4.png /tmp/pngpdf/file\ with\ spaces/5.png output.pdf
Load/Image//tmp/pngpdf/file with spaces[1.png]: 584 of 585, 100% complete
Load/Image//tmp/pngpdf/file with spaces[2.png]: 584 of 585, 100% complete
Load/Image//tmp/pngpdf/file with spaces[3.png]: 584 of 585, 100% complete
Load/Image//tmp/pngpdf/file with spaces[4.png]: 584 of 585, 100% complete
Load/Image//tmp/pngpdf/file with spaces[5.png]: 584 of 585, 100% complete
Mogrify/Image//tmp/pngpdf/file with spaces[5.png]: 4 of 5, 100% complete
resize image[output.pdf]: 180 of 181, 100% complete
resize image[output.pdf]: 180 of 181, 100% complete
resize image[output.pdf]: 180 of 181, 100% complete
resize image[output.pdf]: 180 of 181, 100% complete

これは私を非常に混乱させ、この問題を解決する方法を知りません。私はまた、成功せずにファイル配列で参照されている個々のファイル名を保存してみましたDEBUG: filearray: "/tmp/pngpdf/file with spaces/1.png" "/tmp/pngpdf/file with spaces/2.png" "/tmp/pngpdf/file with spaces/3.png" "/tmp/pngpdf/file with spaces/4.png" "/tmp/pngpdf/file with spaces/5.png"。 bashもこれらの特殊文字をエスケープできます。私はこれがbashの仕組みと関係があると確信していますが、これを自分で理解するのに十分理解できないようです。だから誰かが私に悟ってくれたら、とても嬉しいです。 :)

PS:私はいくつかの場所で私の質問に対する答えを探していました(ファイル名にスペースが含まれるシェルスクリプトの問題生成されたファイル名のリストを引数リストとして使用 - スペースを含める名前にスペースを含むファイルを繰り返しますか?スペースを含むBashスクリプトとファイルスペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?ファイル名にスペースが含まれるスクリプトの問題)。残念ながら、そこに私の質問に対する答えが見つかりません。たぶん遅すぎるかもしれません;)

ベストアンサー1

execcmd="convert -monitor ${filearray[@]} 出力.pdf"

しかし、$execcmdConvertで実行するとエラーがたくさん発生します。

$execcmdファイル名とファイル名のスペースで区切られた部分の区別がすでに失われているため、呼び出さないでください。代わりに、引用符付き引数を使用してコマンド自体を実行してください。

    convert -monitor "${filearray[@]}" output.pdf

おすすめ記事