1. 序章

一連のPDFファイルで特定の文字列の出現を検索することは、私たち自身が非常に頻繁に行っていることです。 これは、次の旅の列車の切符を見つけるなどの個人的なユーティリティや、PDFファイルからデータを抽出する必要があるビジネスユーティリティの場合があります。 GUIビューアを使用して各PDFファイルを手動で開き、文字列を検索することもできますが、ファイルのセットが大きい場合、このプロセスは非常に面倒になります。

コマンドラインツールを使用すると、多数のファイルの検索を簡単に自動化できます。 ただし、PDFはバイナリ形式であり、grepやsedなどのプレーンテキスト検索コマンドはPDFファイルでは期待どおりに機能しないことに注意する必要があります。

このチュートリアルでは、PDFファイル内の文字列を検索するために使用できるいくつかの特殊なコマンドを見ていきます。

2. pdftotextを使用する

pdftotextコマンドは、PDFファイルをプレーンテキストに変換するユーティリティです。ほとんどのLinuxディストリビューションでデフォルトで提供されています。 このコマンドを使用して、すべてのPDFファイルをプレーンテキストに変換し、結果のプレーンテキスト出力に対してgrepを実行できます。 これは複数のステップからなるプロセスです。 したがって、各ステップを1つずつ見てから、すべてのステップを1つのコマンドに結合します。

2.1. PDFファイルをプレーンテキストに変換する

次のように、単一のPDFファイルをプレーンテキストに変換できます。

$ pdftotext filename.pdf -

最後のハイフンは、出力をstdoutに送信するようにコマンドに指示するために使用されます。 それ以外の場合は、出力をテキストファイルに保存します。 さらに処理するために他のコマンドにパイプできるように、出力をstdoutに入れる必要があります。

2.2. PDFファイルでの検索

上記のコマンドから出力されたプレーンテキストをgrepコマンドにパイプして、ファイル内の文字列またはパターンを検索できます。

$ pdftotext train-ticket.pdf - | grep --with-filename --label=train-ticket.pdf -i "bengaluru"
train-ticket.pdf:From: KSR BENGALURU(SBC)
train-ticket.pdf:Boarding At: KSR BENGALURU(SBC)

–with-filenameおよび–label フラグを追加して、一致するたびにファイル名を出力します。 -i フラグは、指定されたパターンで大文字と小文字を区別しない検索を実行するために使用されます。 大文字と小文字を区別する検索を実行するには、これを省略できます。

2.3. フォルダ内のすべてのPDFファイルを検索する

単一のファイルを検索するコマンドができたので、findコマンドを使用してすべてのPDFファイルに対してこれを繰り返す必要があります。 まず、 findコマンドを実行して、現在のフォルダー内のすべてのPDFファイルパスを出力します。

$ find . -name '*.pdf'
./sbc-2022-01-02.pdf
./train-ticket.pdf
./downloads/HR_23-01-2022.pdf
./downloads/subfolder/20-01-2022 HMB English.pdf
./30-01-2022 HMB English.pdf

コマンド内のドットは現在のフォルダーを示しており、他のパスに置き換えて検索できます。 *。pdfas name 引数は、.pdf拡張子を持つファイル名をフィルタリングします。

2.4. ステップを組み合わせる

これで、 findコマンドのexec引数を使用して、各ファイルに対して検索を実行し、結果をファイルごとに出力できます。

$ find . -name '*.pdf' -exec sh -c 'pdftotext "{}" - | grep --with-filename --label="{}" -i bengaluru' \;
./sbc-2022-01-02.pdf:Resv. Upto: KSR BENGALURU(SBC)
./sbc-2022-01-02.pdf:To: KSR BENGALURU(SBC)
./train-ticket.pdf:From: KSR BENGALURU(SBC)
./train-ticket.pdf:Boarding At: KSR BENGALURU(SBC)
./downloads/subfolder/20-01-2022 HMB English.pdf:Bengaluru Urban

find コマンドが、現在のフォルダーとサブフォルダー内のPDFファイルを再帰的に検索していることがわかります。 maxdepth 引数を追加して、フォルダーのみを検索するか、指定されたレベルのサブフォルダーのみを含めることができます。

$ find . -maxdepth 1 -name '*.pdf' -exec sh -c 'pdftotext "{}" - | grep --with-filename --label="{}" -i bengaluru' \;

3. pdfgrepを使用する

pdfgrepコマンドを使用すると、PDFファイルのパターンを1つのステップで検索できます。 ただし、デフォルトではLinuxディストリビューションで使用できない場合があり、使用するにはpdfgrepパッケージをインストールする必要があります。 すべての設定が完了したら、それを使用するのは非常に簡単です。

$ pdfgrep -HiR bengaluru .
./sbc-2022-01-02.pdf:   From: MYSURU JN(MYS)                                                               Date Of Journey: 02-Jan-2022                                                         To: KSR BENGALURU(SBC)
./sbc-2022-01-02.pdf:   Resv. Upto: KSR BENGALURU(SBC)                                                     Scheduled Arrival: 02-Jan-2022 21:05 *                                               Adult: 2 Child: 0
./train-ticket.pdf:   From: KSR BENGALURU(SBC)                                                           Date Of Journey: 01-Jan-2022                                                         To: MYSURU JN(MYS)
./train-ticket.pdf:   Boarding At: KSR BENGALURU(SBC)                                                    Date Of Boarding: 01-Jan-2022                                                        Scheduled Departure: 01-Jan-2022 10:50 *

H オプションを使用してファイル名を印刷し、 i オプションを使用して大文字と小文字を区別せずに検索し、Rオプションを使用して指定されたフォルダー(この場合は現在のフォルダー)。 上で見たように、変換からの出力は大きなスペースで少し厄介になる可能性があります。

4. ripgrep-allを使用する

ユーティリティripgrep-allのrgaコマンドを使用して、PDFファイルやその他のファイル形式のパターンを見つけることができます。 パッケージのインストールは少し面倒ですが、コマンドの使用は非常に簡単です。

$ rga --type pdf bengaluru
sbc-2022-01-02.pdf
Page 1: Resv. Upto: KSR BENGALURU(SBC)
Page 1: To: KSR BENGALURU(SBC)

train-ticket.pdf
Page 1: From: KSR BENGALURU(SBC)
Page 1: Boarding At: KSR BENGALURU(SBC)

このコマンドは、パターンが発生するページ番号だけでなく、ファイル名とともにすべての一致を出力します。

5. 結論

この記事では、PDFファイルのコレクション内の文字列またはパターンを検索するためのさまざまな方法について説明しました。 私たちの最初の方法は、多段階のプロセスでした。 find を実行してすべてのPDFファイルを反復処理し、 pdftotext、 grep を実行して、パターンの出現を検出しました。 これはトリッキーなプロセスですが、デフォルトでほとんどのシステムですでに使用可能なコマンドを使用します。

上記の方法の代わりに、pdfgrepおよびripgrep-allを使用することもできます。 これらはより単純なシングルステップの代替手段ですが、デフォルトではシステムにインストールされていない可能性があります。