9

Я использую Opensuse 10.3 и хотел бы знать инструменты командной строки для поиска фраз в большом количестве PDF-файлов внутри каталога. В Windows XP поиск в проводнике позволяет это сделать, но он слишком медленный. Есть ли здесь советы по grep?

4 ответа4

6
SEARCH_DIR="/some/dir/where/you/want/to/search/";
SEARCH_STRING="whatever-you-are-searching";
# extracting text from pdf
pdftotext "file.pdf" "file.txt"

# connecting with grep
pdftotext "file.pdf" /dev/stdout |grep -H --label="file.pdf" -- "$SEARCH_STRING"

# if you want grep to show only file list of matching pdf file, add --files-with-matches
pdftotext "file.pdf" /dev/stdout |grep -H --label="file.pdf" --files-with-matches -- "$SEARCH_STRING"

# find possible list of pdf to search from
find "$SEARCH_DIR" -type f -name '*.pdf' > list-of-pdf.txt
# everything joined by awk as duct tape, sent to bash for processing
# double quote is escaped as x22 inside awk.
find "$SEARCH_DIR" -type f -name '*.pdf' |awk -v SEARCH_STRING="$SEARCH_STRING" '{
print "pdftotext \x22"$0"\x22 /dev/stdout | grep -H  --label=\x22"$0"\x22 -- \x22"SEARCH_STRING"\x22"
}' |bash

# With out bash. Further process to match your need
find "$SEARCH_DIR" -type f -name '*.pdf' |awk -v SEARCH_STRING="$SEARCH_STRING" '
{
EXEC="pdftotext \x22"$0"\x22 /dev/stdout | grep -H  --label=\x22"$0"\x22 -- \x22"SEARCH_STRING"\x22";
while(EXEC|getline ret){
 print "For file ["$0"] we have match ["ret"]";
 # do whatever you like. 
};
close(EXEC);
}'
3

В Linux и Windows вы можете использовать Acrobat Reader, в котором есть команда для поиска по нескольким файлам.

Под Linux есть Recoll, которая создаст индекс ваших pdf-файлов (и более) при первом запуске. После построения индекса поиск слов должен быть очень быстрым; поиск фразы должен быть разумным. Убедитесь, что команда pdftotext установлена перед запуском Recoll; под Debian и Ubuntu он находится в poppler-utils , я не знаю о Suse.

Или вы можете напрямую преобразовать файлы в текст и использовать grep для текстовых файлов с помощью команд ниже.

find -name '*.pdf' -exec pdftotext {} \;
grep -r --include '*.txt' -l -F "exact phrase to search"
grep -r --include '*.txt' -l -E "regular expression to search"
1

Adobe Reader X делает работу и она позволяет искать под целой директории и поддиректорий, не только внутри файла, но это не программа командной строки.

0

Чтобы рекурсивно вывести список всех файлов в вашем домашнем каталоге, которые имеют расширение PDF и содержат строку, например, соответствующую регулярному выражению ' [iI]n Haskell ', вы можете выполнить:

find ~/ -regextype posix-extended -regex '.*\.pdf' -execdir sh -c 'pdftotext "$0" - | grep -El --label="$PWD${0#?}" "$1"' {} '[iI]n Haskell' \;

Примечания:

  • Хотя это не особенно необходимо для этого примера, я создал это, избегая использования -exec или xargs потому что, по соображениям безопасности, я думаю, что это хорошая практика, чтобы привыкнуть к этому. Замена -execdir на -exec и $PWD${0#?} до ' $0 ' должен достичь того же результата в этом случае.
  • Вместо использования глобусов для сопоставления с образцом имен файлов, может быть полезно использовать большую выразительную силу регулярных выражений и сопоставление с образцом по всему пути. Я включил здесь практику, чтобы показать, как это можно сделать. Обратите внимание, что путь, с которым сопоставляется шаблон, - это путь, который обычно печатается. Являются ли это относительное или абсолютное зависит от заданного пути аргумента (ов), которые , если испускаемый по умолчанию для текущего рабочего каталога ./ '). В этом примере все сопоставленные пути являются абсолютными (т. Е. Начинаются с « / »), поскольку « ~/ » раскрывается до абсолютного пути к домашнему каталогу текущего пользователя и является единственным аргументом пути.
  • ' $0 ' и ' $1 ' - это позиционные параметры, используемые таким образом, чтобы правильно указывать аргументы. Если это не сделано правильно, команда уязвима для произвольных имен файлов.
  • ' ${0#?} ' удаляет первый символ $0 , то есть ' . ».

Для печати каждой подходящей строки следует имя файла:

find ~/ -regextype posix-extended -regex '.*\.pdf' -execdir bash -c 'pdftotext "$0" - | grep -EH --label="${0:2}" "$1"' {} '[iI]n Haskell' \;

Этот вариант использует ' -H ' вместо ' -l ' и помечает имя файла, а не путь к файлу. « ${0:2} » удаляет первые два символа $0 , то есть « ./ », но, очевидно, sh не распознает sh .

Конечно, подстраивайтесь под свои нужды.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .