Как я могу grep в файлах PDF?

136

Есть ли способ поиска PDF-файлов с использованием возможностей grep, без предварительного преобразования в текст в Ubuntu?

Дервин Танк
источник
1
Я думаю, что вам нужно проанализировать его в pdf2text, чтобы получить полезные результаты ...
Йохан
1
Для людей, которые приходят сюда с помощью поиска: Если вы хотите сначала преобразовать его в текстовые файлы, ознакомьтесь с разделом Как искать содержимое нескольких файлов PDF?
Мартин Тома

Ответы:

135

Установите пакет pdfgrep, затем используйте команду:

find /path -iname '*.pdf' -exec pdfgrep pattern {} +

------

Самый простой способ

pdfgrep 'pattern' *.pdf
pdfgrep 'pattern' file.pdf 
enzotib
источник
5
Это работает и в Mac OSX (Mavericks). Установите его с помощью варева. Просто. Благодарю.
mikiemorales
7
Из любопытства я проверил источник pdfgrep, и он использует poppler для извлечения строк из pdf. Почти точно так же, как ответ @ wag только постранично, а не, по-видимому, весь документ.
Эндрю Мартин
4
pdfgrepтакже имеет рекурсивный флаг. Так что этот ответ может возможно быть уменьшена до: pdfgrep -R pattern /path/. Хотя это может быть менее эффективно, если он просматривает каждый файл, даже если это не PDF. И я замечаю, что у него есть проблемы с международными символами, такими как å, ä и ö.
Рованион
1
На самом деле, эта -nопция является про для pdfgrep, так как позволяет включить номер страницы в вывод (может быть полезным для дальнейшей обработки).
JepZ
4
Этот ответ было бы проще использовать, если бы он объяснил, какие биты команды предназначены для буквального копирования, а какие являются заполнителями. Что pattern? Что {}? Что случилось с `+`? Я не имею ни малейшего представления при первом прочтении ... так что, пожалуй, я перехожу к руководству.
Марк Амери
56

Если вы poppler-utilsустановили (по умолчанию на Ubuntu Desktop), вы можете «конвертировать» его на лету и направить в grep:

pdftotext my.pdf - | grep 'pattern'

Это не создаст файл .txt.

шутник
источник
1
итак ... вы извлекаете текст перед тем, как вводить его, что означает ответ "нет".
Акира
18
@akira ОП, вероятно, означало «не открывать PDF в программе просмотра и не экспортировать в текст»
Майкл Мрозек
5
@akira Где вы видите "только grep"?
Михаил Мрозек
6
@akira Ну, я уже сказал, что, вероятно, он имел в виду; он не хочет экспортировать в текст перед обработкой. Я очень сомневаюсь, что у него есть проблемы с любой командой, которая преобразуется в текст любым способом; нет причин не делать этого
Майкл Мрозек
2
@sherrellbc Второй аргумент pdftotext- это имя файла, в которое он должен писать. Тем не менее, по соглашению, инструменты обычно позволяют записывать stdoutвместо файла, указав -вместо этого. Точно так же некоторые инструменты будут писать stdoutпо умолчанию, если вы полностью пропустите такой аргумент (но это не всегда возможно без создания неоднозначности).
Joost
12

pdfgrep был написан именно для этой цели и доступен в Ubuntu.

Он пытается быть в основном совместимым с grepи, таким образом, предоставляет «мощь grep», предназначенную только для PDF-файлов. Это включает в себя общие параметры grep, такие как --recursive, --ignore-caseили --color.

В отличие от pdftotext | greppdfgrep может выводить номер страницы соответствия быстрым способом и обычно быстрее, когда не нужно искать весь документ (например, --max-countили --quiet).

Основное использование:

pdfgrep PATTERN FILE..

где PATTERNваша строка поиска и FILEсписок имен файлов (или подстановочные знаки в оболочке).

Смотрите man-страницу для получения дополнительной информации.

hpdeifel
источник
7

Нет.

PDF состоит из кусков данных, некоторые из которых текстовые, некоторые из них рисунки, а некоторые из них действительно волшебно причудливые XYZ (например, файлы .u3d). Эти фрагменты в большинстве случаев сжимаются (например, flat, проверьте http://www.verypdf.com/pdfinfoeditor/compression.htm ). Для того, чтобы 'grep' .pdf, вы должны обратить сжатие или извлекать текст.

Вы можете сделать это либо для каждого файла с помощью таких инструментов, как pdf2textи grep результата, либо запустить 'indexer' (посмотрите на xapian.org или lucene ), который создает индекс для поиска из ваших файлов .pdf, а затем вы можете использовать поиск инструменты движка этого индексатора для получения содержимого PDF.

Но нет, вы не можете greppdf файлы и надеяться на надежные ответы без предварительного извлечения текста.

Акира
источник
5
Учитывая pdfgrepсуществование (см. Выше), плоское «нет» неверно.
Джонатан Кросс
6

Recoll может искать PDF-файлы. Он не поддерживает регулярные выражения, но имеет множество других параметров поиска, поэтому он может соответствовать вашим потребностям.

user39336
источник
5

Вы могли бы передать это stringsсначала:

cat file.pdf | strings | grep <...etc...>
Энди Смит
источник
8
Просто используйте strings file.pdf | grep <...>, вам не нужноcat
phunehehe
Да, мой разум, кажется, лучше работает с потоками ... :-)
Энди Смит
12
не будет работать, если текст сжат, что происходит в большинстве случаев.
Акира
6
Даже если текст не сжат, это, как правило, небольшие фрагменты предложений (даже не обязательно целые слова!), Которые точно смешаны с форматированием информации. Не очень дружелюбный для stringsили grep.
Jander
Можете ли вы придумать другую причину, по которой использование строк для этого не сработает? Я обнаружил, что использование строк работает с некоторыми PDF-файлами, но не с другими.
hourback
3

Взгляните на общий ресурс grep tool crgrep, который поддерживает поиск в файлах PDF.

Он также позволяет искать другие ресурсы, такие как содержимое, вложенное в архивы, таблицы базы данных, метаданные изображений, зависимости файлов POM и веб-ресурсы - и их комбинации, включая рекурсивный поиск.

Craig
источник
2

попробуй это

find /path -iname *.pdf -print0 | for i in `xargs 0`; do echo $i; \
    pdftotext "$i" - | grep pattern; done

для печати линий шаблон происходит внутри PDF

harish.venkat
источник
2

Перейдите в вашу папку, содержащую ваш PDF-файл, а затем ..

pdfgrep 'pattern' your.pdf

или если вы хотите искать в более чем одном PDF-файле (например, во всех PDF-файлах в вашей папке)

pdfgrep 'pattern'  `ls *.pdf`

или же

pdfgrep 'pattern' $(ls *.pdf)
Расмусс Ралл
источник
с какой стати вы используете ls для ввода имен файлов в параметры? Это не только медленнее, но и плохая идея использовать lsвывод как ввод для других команд . Просто pdfgrep 'pattern' *.pdfдостаточно
phuclv
1

В StackOverflow есть повторяющийся вопрос. Люди там предлагают вариант ответа harish.venkarts:

find /path -name '*.pdf' -exec sh -c 'pdftotext "{}" - | grep --with-filename --label="{}" --color "your pattern"' \;

Преимущество перед аналогичным ответом здесь - --with-filenameфлаг для grep. Это также несколько лучше pdfgrep, потому что стандартный grep имеет больше возможностей.

https://stackoverflow.com/questions/4643438/how-to-search-contents-of-multiple-pdf-files

user7610
источник
Я думаю, что было бы лучше оставить это как комментарий (или редактировать) в аналогичном ответе, на который вы ссылаетесь.
Бернхард
0

Вот быстрый скрипт для поиска pdf в текущем каталоге:

#!/bin/bash

if [ $# -ne 1 ]; then
  echo "usage $0 VALUE" 1>&2
  exit 1
fi

echo 'SEARCH IS CASE SENSITIVE' 1>&2

find . -name '*.pdf' -exec /bin/bash -c 'pdftotext "{}" - | grep --with-filename --label="{}" --color "$0"' $1 \;
Нико
источник
0

Я предполагаю, что вы имеете в виду, что tp не конвертирует его на диск, вы можете конвертировать их в stdoutи затем делать это с помощью grep pdftotext. Grepping pdf без какого-либо преобразования не является практическим подходом, так как PDFэто в основном двоичный формат.

В каталоге:

ls -1 ./*.pdf | xargs -L1 -I {} pdftotext {}  - | grep "keyword"

или в каталоге и его подкаталогах:

tree -fai . | grep -P ".pdf$" | xargs -L1 -I {} pdftotext {}  - | grep "keyword"

Кроме того, поскольку некоторые из них pdfявляются сканированием, они должны быть сначала OCRed. Я написал довольно простой способ поиска по всем PDF-файлам, которые не могут быть grepотредактированы, и OCR их.

Я заметил, что если pdfфайл не имеет какого-либо шрифта, он обычно не доступен для поиска. Итак, зная это, мы можем использовать pdffonts.

Первые 2 линии pdffontsявляются заголовок таблицы, поэтому , если файл поиска имеет более чем два выходных линий, зная это , мы можем создать:

gedit check_pdf_searchable.sh

затем вставьте это

#!/bin/bash 
#set -vx
if ((`pdffonts "$1" | wc -l` < 3 )); then
echo $1
pypdfocr "$1"
fi

затем сделайте его исполняемым

chmod +x check_pdf_searchable.sh

затем перечислите все не доступные для поиска PDF-файлы в каталоге:

ls -1 ./*.pdf | xargs -L1 -I {} ./check_pdf_searchable.sh {}

или в каталоге и его подкаталогах:

tree -fai . | grep -P ".pdf$" | xargs -L1 -I {} ./check_pdf_searchable.sh {}
Эдуард Флоринеску
источник
0

Если вы просто хотите искать pdf-имена / свойства ... или простые строки, которые не сжимаются и не кодируются, тогда вместо stringsвас можно использовать

grep -a STRING file.pdf
cat -v file.pdf | grep STRING

От grep --help:

      --binary-files=TYPE   assume that binary files are TYPE;
                            TYPE is 'binary', 'text', or 'without-match'
  -a, --text                equivalent to --binary-files=text

и cat --help:

  -v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB
phuclv
источник
0

Возможно, вам нужен gpdf, если вы используете Gnome! Проверьте это на случай, если вы не используете Gnome. У него есть список зрителей PDF CLI. Затем вы можете использовать, grepчтобы найти шаблон.

Dharmit
источник