質問

質問

何千ものPDFファイルを1つのフォルダに繰り返し圧縮する予定です。

次のループを試してみました。

#!/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が最初に/を持ち、processor / $fileも試したのでprocessor $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"

ループが機能しない理由のアイデアはありますか?
PS すべてのディレクトリは、777 で許可エラーがないことを確認します。

答え1

質問

デフォルトでは、find次の操作が実行されます-print

 -print

True の場合、標準出力にファイル名全体を印刷し、その後に改行文字が続きます。

「フルファイル名」は、各ファイルの絶対パスが表示されることを意味する。

/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

事実印刷滞在標準出力は、「\」エスケープ文字と「%」ディレクティブを解釈します。

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).

相対的な名前を使用してください

または(入力ファイルが別のディレクトリにある場合)、クリーンアップする必要があります。一部ディレクトリパス。たとえば、使用できます。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番目の入力までのすべての内容が削除されます。ただし、入力ツリーの構造と一致するように、新しい出力ディレクトリの作成は処理されません。

答え2

複数のテストを行った後、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ファイルを生成できます。あなたのコマンドを使ってPDFファイルを生成することができるので、gs他に問題はないとします。

スクリプトの完了後にターゲットに空のディレクトリがあると思われ、それを削除したい場合は、次のfindコマンドを使用してください。

find /home/user/processed/ -type d -empty -delete

関連情報