Jak mogę grepować w plikach PDF?


135

Czy istnieje sposób wyszukiwania plików pdf za pomocą grep, bez konwersji do tekstu w systemie Ubuntu?


1
Myślę, że musisz go przeanalizować w formacie pdf2text, aby uzyskać z powrotem użyteczne wyniki ...
Johan


1
Dla osób przybywających tutaj przez wyszukiwanie: jeśli chcesz najpierw przekonwertować go na pliki tekstowe, zapoznaj się z tematem Jak przeszukiwać zawartość wielu plików pdf?
Martin Thoma,

Odpowiedzi:


135

Zainstaluj pakiet pdfgrep, a następnie użyj polecenia:

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

——————

Najprościej jest

pdfgrep 'pattern' *.pdf
pdfgrep 'pattern' file.pdf 

5
Działa to również w systemie Mac OSX (Mavericks). Zainstaluj go za pomocą naparu. Prosty. Dzięki.
mikiemorales

7
Z ciekawości sprawdziłem źródło pdfgrep i używa popplera do wydobywania ciągów z pdf. Prawie dokładnie tak, jak odpowiedź @ wag tylko po prostu pagodise, a nie, prawdopodobnie, cały dokument.
Andrew Martin

4
pdfgrepma również flagę rekurencyjną. Więc to może być odpowiedź może być skrócony do: pdfgrep -R pattern /path/. Chociaż może być mniej skuteczny, jeśli przejdzie przez każdy plik, nawet jeśli nie jest to plik PDF. Zauważam, że ma problemy ze znakami międzynarodowymi, takimi jak å, ä i ö.
Rovanion

1
W rzeczywistości -nopcja ta jest pro dla pdfgrep, ponieważ pozwala dołączyć numer strony do wyniku (może być pomocny w dalszym przetwarzaniu).
JepZ

4
Ta odpowiedź byłaby łatwiejsza w użyciu, gdyby wyjaśniła, które bity polecenia mają zostać skopiowane dosłownie, a które to symbole zastępcze. Co jest pattern? Co jest {}? O co chodzi z `+`? Po pierwszym czytaniu nie mam pojęcia ... więc chyba idę do strony podręcznika.
Mark Amery

56

Jeśli masz poppler-utilszainstalowany (domyślnie na Ubuntu Desktop), możesz go „przekonwertować” w locie i potokować do grep:

pdftotext my.pdf - | grep 'pattern'

To nie utworzy pliku .txt.


1
więc ... wyodrębniasz tekst przed grepem, co oznacza, że ​​odpowiedź brzmi „nie”.
akira

18
@akira OP prawdopodobnie oznaczało „bez otwierania pliku PDF w przeglądarce i eksportowania do tekstu”
Michael Mrozek

5
@akira Gdzie widzisz „tylko grep”?
Michael Mrozek

6
@akira Cóż, już powiedziałem, co myślę, że prawdopodobnie miał na myśli; nie chce eksportować do tekstu przed przetworzeniem. Bardzo wątpię, aby miał problem z dowolnym poleceniem, które konwertuje na tekst w jakikolwiek sposób; nie ma powodu, aby tego nie
robić

2
@ sherrellbc Drugim argumentem pdftotextjest nazwa pliku, do którego powinien zapisać. Jednak, zgodnie z konwencją, narzędzia zazwyczaj pozwalają na pisanie do stdoutpliku zamiast do pliku poprzez podanie -zamiast niego. Podobnie niektóre narzędzia zapisują stdoutdomyślnie, jeśli całkowicie pominie się taki argument (ale nie zawsze jest to możliwe bez tworzenia niejednoznaczności).
Joost

11

pdfgrep został napisany właśnie w tym celu i jest dostępny w Ubuntu.

Stara się być w większości kompatybilny, grepa tym samym zapewnia „moc grep”, specjalizującą się tylko w plikach PDF. Która obejmuje wspólne opcje grep, takie jak --recursive, --ignore-caselub --color.

W przeciwieństwie do pdftotext | greppdfgrep może wypisać numer strony dopasowania w wydajny sposób i generalnie jest szybszy, gdy nie musi przeszukiwać całego dokumentu (np. --max-countLub --quiet).

Podstawowym zastosowaniem jest:

pdfgrep PATTERN FILE..

gdzie PATTERNjest szukany ciąg i FILElista nazw plików (lub symboli wieloznacznych w powłoce).

Zobacz manpage cej informacje o.


7

Nie.

Plik pdf składa się z fragmentów danych, niektórych tekstów, niektórych zdjęć, a niektóre naprawdę magicznych, fantazyjnych XYZ (np. Plików .u3d). Te fragmenty są w większości skompresowane (np. Płaskie, sprawdź http://www.verypdf.com/pdfinfoeditor/compression.htm ). Aby „grep” .pdf trzeba odwrócić kompresję, czyli wyodrębnić tekst.

Możesz to zrobić albo dla każdego pliku za pomocą narzędzi, takich jak pdf2texti grep, lub uruchomić „indeksator” (spójrz na xapian.org lub lucene ), który buduje indeks z plików pdf do przeszukiwania, a następnie możesz użyć wyszukiwania narzędzia silnikowe tego indeksatora, aby uzyskać zawartość pliku pdf.

Ale nie, nie można greppdfować plików i mieć nadzieję na wiarygodne odpowiedzi bez uprzedniego wyodrębnienia tekstu.


5
Biorąc pod uwagę, że pdfgrepistnieje (patrz wyżej), płaskie „nie” jest nieprawidłowe.
Jonathan Cross

6

Recoll może wyszukiwać pliki PDF. Nie obsługuje wyrażeń regularnych, ale ma wiele innych opcji wyszukiwania, więc może pasować do twoich potrzeb.


5

Możesz stringsnajpierw przepuścić przez : -

cat file.pdf | strings | grep <...etc...>

8
Po prostu użyj strings file.pdf | grep <...>, nie potrzebujeszcat
phunehehe

Tak - wydaje mi się, że mój umysł lepiej działa ze strumieniami: :-)
Andy Smith

12
nie zadziała, jeśli tekst jest skompresowany, co jest przez większość czasu.
akira

6
Nawet jeśli tekst nie jest skompresowany, to na ogół małe fragmenty zdań (niekoniecznie całe słowa!) Drobno zmieszane z informacjami o formatowaniu. Niezbyt przyjazny dla stringslub grep.
Jander

Czy możesz wymyślić inny powód, dla którego użycie ciągów do tego nie zadziałałoby? Odkryłem, że używanie ciągów działa na niektórych plikach PDF, ale nie na innych.
hourback

3

Spójrz na wspólne narzędzie crgrep grep zasobów, które obsługuje wyszukiwanie w plikach PDF.

Umożliwia także wyszukiwanie innych zasobów, takich jak zawartość zagnieżdżona w archiwach, tabele bazy danych, metadane obrazu, zależności plików POM i zasoby sieciowe - oraz ich kombinacje, w tym wyszukiwanie rekurencyjne.


2

Spróbuj tego

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

do drukowania linii wzór pojawia się w pliku pdf


2

cd do twojego folderu zawierającego plik pdf, a następnie ...

pdfgrep 'pattern' your.pdf

lub jeśli chcesz wyszukać więcej niż jeden plik pdf (np. we wszystkich plikach pdf w swoim folderze)

pdfgrep 'pattern'  `ls *.pdf`

lub

pdfgrep 'pattern' $(ls *.pdf)

dlaczego, u licha, używasz ls do umieszczania nazw plików w parametrach? Używanie lsdanych wyjściowych jako danych wejściowych do innych poleceń jest nie tylko wolniejsze, ale również złym pomysłem . Po prostu pdfgrep 'pattern' *.pdfwystarczy
phuclv

1

W StackOverflow istnieje zduplikowane pytanie. Ludzie tam sugerują odmianę harish.venkarts odpowiedzi:

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

Przewagą nad podobną odpowiedzią jest --with-filenameflaga grep. Jest to nieco lepsze niż pdfgrep, ponieważ standardowy grep ma więcej funkcji.

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


Myślę, że lepiej zostawić to jako komentarz (lub edycję) w podobnej odpowiedzi, o której mówisz.
Bernhard

0

Oto krótki skrypt do wyszukiwania pdf w bieżącym katalogu:

#!/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

Zakładam, że masz na myśli, że tp nie konwertuje go na dysk, możesz przekonwertować je na, stdouta następnie grep go pdftotext. Grepowanie pdf bez jakiejkolwiek konwersji nie jest praktycznym podejściem, ponieważ PDFjest to głównie format binarny.

W katalogu:

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

lub w katalogu i jego podkatalogach:

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

Ponieważ niektóre pdfsą skanami, najpierw należy je OCRed. Napisałem dość prosty sposób na przeszukiwanie wszystkich plików PDF, których nie można grepedytować i ich OCR.

Zauważyłem, że jeśli pdfplik nie ma żadnej czcionki, zwykle nie można go przeszukiwać. Wiedząc o tym, możemy skorzystać pdffonts.

Pierwsze 2 wiersze pdffontsnagłówka tabeli, więc gdy plik do przeszukiwania ma więcej niż dwa wiersze, wiedząc, że możemy to utworzyć:

gedit check_pdf_searchable.sh

następnie wklej to

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

następnie uczyń go wykonywalnym

chmod +x check_pdf_searchable.sh

następnie wypisz wszystkie nieprzeszukiwalne pliki pdf w katalogu:

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

lub w katalogu i jego podkatalogach:

tree -fai . | grep -P ".pdf$" | xargs -L1 -I {} ./check_pdf_searchable.sh {}

0

Jeśli chcesz po prostu wyszukać nazwy / właściwości pdf ... lub proste ciągi, które nie są kompresowane ani kodowane, zamiast tego stringsmożesz użyć poniższych

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

Od 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

i cat --help:

  -v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB

0

gpdf może być tym, czego potrzebujesz, jeśli używasz Gnome! Zaznacz to, jeśli nie używasz Gnome. Ma listę przeglądarek pdf CLI. Następnie możesz użyć, grepaby znaleźć wzór.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.