フォルダー内の数千のPDFファイルを再帰的に圧縮するつもりです。
次のループで試しました:
#!/bin/bash
find "/home/user/original" -type f -name *.pdf | while read -r file
do
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress -dNOPAUSE -dBATCH -dQUIET -sOutputFile="/home/user/processed$file" "$file"
done
($ fileは最初に/をもたらすため、processed $ fileが使用され、processed/$ fileも試しました)
とにかく、ループを実行すると次のエラーが発生します。
GPL Ghostscript 9.26: **** Could not open the file /home/user/processed/home/user/original/test001.pdf .
**** Unable to open the initial device, quitting.
何らかの理由で、path/to/output/path/to/inputでpdfを探しています。 /ではなく./リンクに変更しようとしましたが、役に立ちませんでした。
以下を単独で実行すると、圧縮されたpdfが適切に出力されます。
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress -dNOPAUSE -dBATCH -dQUIET -sOutputFile="/home/user/processed/output.pdf" "input.pdf"
ループが機能しない理由はありますか?
P.S。パーミッションエラーがないことを確認するために、今のところすべてのディレクトリは777です。
数回テストした後、Ghostscriptで次の動作を観察しました。出力ファイルを/home/user/processed/home/user/original/test001.pdf
として指定すると、gs
コマンドは、ファイル(/home/user/processed/home/user/original/
)に至るパスがすでに存在することを想定しています。ソースのフォルダ構造は現在宛先に存在しないため、コマンドはエラーをスローし、宛先ファイルを開くことができないことを示します。
これを修正するには、最初に次のコマンドを使用してフォルダー構造を再作成します。
cd /home/user/original
find . -type d -exec mkdir -p -- /home/user/processed/{} \;
これが完了したら、スクリプトを実行してPDFファイルを生成できます。gs
コマンドを使用してPDF =ファイルなので、これ以上問題はないと思います。
スクリプトの完了後、宛先に空のディレクトリがあると思われ、それらを削除したい場合は、次のfindコマンドを使用します。
find /home/user/processed/ -type d -empty -delete
デフォルトでは、find
は-print
アクションを実行します。
本当;完全なファイル名を標準出力に出力し、その後に改行を続けます。
「完全なファイル名」は、各ファイルへの絶対パスが表示されることを意味します。
/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf
だからあなたが使うとき
gs -sOutputFile="/home/user/processed$file"
...ループ内では、変数$file
に/home/user/original/test001.pdf
が含まれ、式全体が連結された2つのパスに展開されます。
gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"
これは、表示されたエラーメッセージに反映されています。
Could not open the file /home/user/processed/home/user/original/test001.pdf
ファイルのベース名のみが必要な場合(すべてのファイルが同じソースフォルダーにあるため)、find
に別の出力形式を使用するように指示できます。
find "/home/user/original" -type f -name *.pdf -printf '%f\n'
-printf format
本当; print format標準出力で、 `\ 'エスケープと`%'ディレクティブを解釈します。
[...]
\n Newline. %f File's name with any leading directories removed (only the last element).
または(入力ファイルが異なるディレクトリにある場合)、ディレクトリパスのsomeを削除する必要があります。あなたは例えばを使うことができます。そのためのcut
:
find "/home/user/original" -type f -name *.pdf | cut -d/ -f5- | while read -r file
do
gs [...] -sOutputFile="/home/user/processed/$file" "/home/user/original/$file"
これにより、入力の4番目の/
までのすべてが削除されます。ただし、入力ツリーの構造に一致する新しい出力ディレクトリの作成は処理されません。