Я использую Opensuse 10.3 и хотел бы знать инструменты командной строки для поиска фраз в большом количестве PDF-файлов внутри каталога. В Windows XP поиск в проводнике позволяет это сделать, но он слишком медленный. Есть ли здесь советы по grep?
4 ответа
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); }'
В 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"
Adobe Reader X делает работу и она позволяет искать под целой директории и поддиректорий, не только внутри файла, но это не программа командной строки.
Чтобы рекурсивно вывести список всех файлов в вашем домашнем каталоге, которые имеют расширение 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 .
Конечно, подстраивайтесь под свои нужды.