Grep, ack-grep, find, sort, *.pdf
Grep, ack-grep, find, sort, *.pdf
Hallo,
lange arbeite ich noch nicht mit der bash, jedenfalls nicht mit regular expressions und komplizierten Suchanfragen. Und da kommt meine Frage her:
Ich möchte meine *.pdf - und *.html - Dateien in einem Ordner mit drei oder vier Unterordnern nach, sagen wir mal 'find' durchsuchen. Die Ausgabe darf gerne Datei und Zeilennummern enthalten und darf auch in .txt umgeleitet werden - mir raucht schon der Kopp! grep und egrep liefern alle nicht befriedigende Ergebnisse, ack-grep kennt *.pdf nicht...
Habt ihr da einen Tipp? Würde mich riesig freuen!
Ich bedanke mich schommal für eure Mühen
Dietrich
lange arbeite ich noch nicht mit der bash, jedenfalls nicht mit regular expressions und komplizierten Suchanfragen. Und da kommt meine Frage her:
Ich möchte meine *.pdf - und *.html - Dateien in einem Ordner mit drei oder vier Unterordnern nach, sagen wir mal 'find' durchsuchen. Die Ausgabe darf gerne Datei und Zeilennummern enthalten und darf auch in .txt umgeleitet werden - mir raucht schon der Kopp! grep und egrep liefern alle nicht befriedigende Ergebnisse, ack-grep kennt *.pdf nicht...
Habt ihr da einen Tipp? Würde mich riesig freuen!
Ich bedanke mich schommal für eure Mühen
Dietrich
debian 3.10-2-686-pae #1 SMP Debian 3.10.7-1 (2013-08-17) i686 GNU/Linux
Re: Grep, ack-grep, find, sort, *.pdf
Man muss das auftrennen in zwei Aufgaben:-print0 und -0 sorgen dafuer, dass "komische" Dateinamen ohne versehentliches Auftrennen an xargs weitergegeben wird, welches effektivstartet. -n sorgt fuer Dateiname und Zeilennummer im Output.
Gruss Cae
- "finde rekursiv alle Dateien mit Namen *.pdf oder *.html" und
- "suche in diesen Dateien nach pattern".
Code: Alles auswählen
$ find /path -iname '*.pdf' -o -iname '*.html' -print0 | xargs -0 grep -n find >output.txt
Code: Alles auswählen
grep -n find /path/a/foo /path/a/bar /path/b/foo...
Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.
—Bruce Schneier
Re: Grep, ack-grep, find, sort, *.pdf
Wenn grep mehrere Dateien selbst einliest (also nicht über Pipe bzw. stdin), gibt:
Dateinamen und Zeilennummern mit aus, wenn "Muster" gefunden wurde.
Bei PDFs wirst Du wohl zumindest mit pdftotext oder vergleichbaren Tools vorarbeiten müssen. Oder ein spezielles "pdf-grep" nutzen (falls es so etwas gibt). Und auch damit gibt es keine Erfolgsgarantie, denn Texte können in PDFs auch als Grafiken vorliegen.
Cae war schneller. find -exec kann xargs hier übrigens ersetzen, wenn anstelle \; ein + benutzt wird.
Code: Alles auswählen
grep -n Muster Datei1 Datei2 ...
Bei PDFs wirst Du wohl zumindest mit pdftotext oder vergleichbaren Tools vorarbeiten müssen. Oder ein spezielles "pdf-grep" nutzen (falls es so etwas gibt). Und auch damit gibt es keine Erfolgsgarantie, denn Texte können in PDFs auch als Grafiken vorliegen.
Cae war schneller. find -exec kann xargs hier übrigens ersetzen, wenn anstelle \; ein + benutzt wird.
Re: Grep, ack-grep, find, sort, *.pdf
Wprde eher das empfehlen:
Denn pdf sind nciht im klartext und find findet mitunter sehr viele Dateien. – Zu vile für xargs.
Allerdings: pdf zu dursuchen ist langwierig.
Edit: Phineas war großteils schneller
Code: Alles auswählen
find /path -iname '*.html' -exec grep -n find {} \; >output.txt
find ./path -iname '*.pdf' -exec echo "pdf2txt {} | grep -q find && echo {}" \; | bash 2> /dev/null >output2.txt
Allerdings: pdf zu dursuchen ist langwierig.
Edit: Phineas war großteils schneller
rot: Moderator wanne spricht, default: User wanne spricht.
Re: Grep, ack-grep, find, sort, *.pdf
Du hast Deine Befehle nicht getestet, gelle wanne? Die liefern keinen Dateinamen. Warum, steht in meinem Beitrag ("mehrere Dateien"). Im Ersten Befehl brauchst Du nur das \; ersetzen.
Re: Grep, ack-grep, find, sort, *.pdf
Gerade weil find vermutlich einen Riesenhaufen Dateien ausgibt, wuerde ich xargs verwenden. Sonst hat man fuer jede Datei einen fork() fuer ein eigenes grep, womoeglich sogar noch mit sh -c. Da ist es garantiert performanter ein einzelnes grep einige wenige Male zu starten, aber mit 50 Dateien als Argument.
Gruss Cae
Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.
—Bruce Schneier
Re: Grep, ack-grep, find, sort, *.pdf
Woran liegt es, dass meine Posts nicht gelesen werden? Zum 3. Mal: das + macht den Unterschied. Beweis:Cae hat geschrieben:Sonst hat man fuer jede Datei einen fork() fuer ein eigenes grep, womoeglich sogar noch mit sh -c.
Code: Alles auswählen
~> mkdir testordner
~> cd testordner/
~/testordner> # 200 Testdateien erstellen:
~/testordner> for f in {1..200}; do >$f; done
~/testordner> # mit fork:
~/testordner> find ./ -type f -exec echo {} \;
./105
./128
./33
[gekürzt]
./121
./80
./160
~/testordner> # ohne fork:
~/testordner> find ./ -type f -exec echo {} +
./105 ./128 ./33 ./116 ./31 ./171 ./161 ./17 ./101 ./149 ./136 ./152 ./122 ./10 ./40 ./102 ./195 ./61 ./35 ./26 ./115 ./107 ./145 ./132 ./112 ./25 ./16 ./64 ./151 ./3 ./177 ./179 ./84 ./131 ./9 ./93 ./111 ./72 ./73 ./159 ./125 ./191 ./141 ./32 ./104 ./75 ./88 ./126 ./127 ./147 ./58 ./106 ./97 ./163 ./189 ./90 ./95 ./200 ./114 ./8 ./119 ./150 ./39 ./44 ./182 ./185 ./21 ./192 ./2 ./70 ./6 ./174 ./67 ./165 ./76 ./167 ./60 ./142 ./65 ./198 ./113 ./103 ./1 ./36 ./176 ./11 ./196 ./91 ./29 ./52 ./156 ./85 ./38 ./170 ./89 ./188 ./183 ./137 ./98 ./37 ./5 ./20 ./180 ./15 ./56 ./194 ./193 ./63 ./169 ./87 ./34 ./140 ./118 ./69 ./12 ./133 ./138 ./173 ./28 ./77 ./184 ./49 ./50 ./53 ./45 ./109 ./99 ./129 ./135 ./168 ./74 ./23 ./172 ./18 ./94 ./164 ./178 ./47 ./62 ./100 ./43 ./144 ./153 ./187 ./41 ./46 ./110 ./82 ./24 ./51 ./181 ./158 ./55 ./48 ./134 ./57 ./162 ./54 ./175 ./27 ./86 ./124 ./4 ./14 ./22 ./7 ./146 ./166 ./120 ./68 ./78 ./81 ./108 ./123 ./130 ./42 ./96 ./30 ./79 ./157 ./148 ./117 ./190 ./197 ./186 ./71 ./19 ./92 ./139 ./154 ./66 ./59 ./13 ./199 ./83 ./155 ./143 ./121 ./80 ./160
~/testordner>
Re: Grep, ack-grep, find, sort, *.pdf
Ein fork braucht hier ca. 0,2 ms. Bei der maximalanzahl der Parameter, die mein 64Bit 3.2 Linux schafft sind das dann wirklich über 3 Minuten. Bei nem 2.6.23 32Bit währen es nur 0,6 Sekunden.Cae hat geschrieben:Gerade weil find vermutlich einen Riesenhaufen Dateien ausgibt, wuerde ich xargs verwenden. Sonst hat man fuer jede Datei einen fork() fuer ein eigenes grep, womoeglich sogar noch mit sh -c. Da ist es garantiert performanter ein einzelnes grep einige wenige Male zu starten, aber mit 50 Dateien als Argument.
Allerdings heißt das noch lange nicht, dass das grep auch wirklich mitmacht. mv verhällt sich z.B. bei mehr als 23693 Parametern komisch. (Das währen mit Fork dann 5 Sekunden.)
Letztendlich wird der fork beim pdf2txt nicht ins gewicht fallen.
Die fork() sparerei ist zwar ein Sport dem auch ich gerne nachhänge sinnvoll ist sie aber glaube ich nicht. Gerade mit mv und xargs hatte ich jetzt schon ein paar mal ärger.
Der 2. Funktioniert schon.Phineas hat geschrieben:m Ersten Befehl brauchst Du nur das \; ersetzen.
Beim ersten habe ich bei dir kopiert ohne genau hinzusehen gemeint war natürlich das:
Code: Alles auswählen
find /path -iname '*.html' -exec grep -l find {} \; >output.txt
rot: Moderator wanne spricht, default: User wanne spricht.
Re: Grep, ack-grep, find, sort, *.pdf
Danke wegen der Mühe, die ihr euch gegeben habt, aber...
Es klappt nicht.
Ich habe xargs gepiped und ich habe -exec getestet, das hatte ich schon vorher. Das Prob ist: find liefert nicht die Ausgaben, die ich brauche. Was ich bekomme, sind Fundstellen von *.html, aber nichts aus den *.pdf-Dateien. Im Ordner -Pfad/Linux/Allgemein befinden sich 3 Ordner und 72 Files - 2 der Ordner sind *.html, der Rest sind *.pdf-Dateien. Ene davon heißt sogar 'grep.pdf, sonst sind da so Sachen wie 'The_Linux_Command_Line' von William E. Shotts - da sollten doch ein paar 'grep' oder 'find' - Fundstellen möglich sein?
'find ~/eBooks/Linux/Allgemein -iname '*.html' -o -iname '*.pdf' -exec grep -n grep {} \; >output.txt' - ergibt leere Datei output.txt
find ~/eBooks/Linux/Allgemein -iname '*.html' -o -iname '*.pdf' -exec grep -n find {} \; >output.txt - dito
find ~/eBooks/Linux/Allgemein -iname '*.pdf' -print0 | xargs -0 grep -n find >output.txt - dito
find ~/eBooks/Linux/Allgemein -iname '*.pdf' -o -iname '*.html' -print0 | xargs -0 grep -n find >output.txt - findet immerhin was in meinen *.html - Dateien...
Ich weiß nix mehr...
[oder?]
Das hier hab ich noch getestet: 'find ~/eBooks/Linux/Allgemein -iname '*.pdf' -exec grep -ln grep {} \;
Ausgabe:
... wenigstens etwas...
Das hier 'find ~/eBooks/Linux/Allgemein -iname '*.pdf' -exec grep -n grep {} \;' dagegen lieferte dies:
(Ich sage vorher schonmal gute Nacht und danke schön! Ich musste die Ausgabe wg erlaubter 50.000 Zeichen etwas kürzen )
Damit das hier lesbar bleibt von wanne gekürzt und in Code-Blöcke gesetzt.
Es klappt nicht.
Ich habe xargs gepiped und ich habe -exec getestet, das hatte ich schon vorher. Das Prob ist: find liefert nicht die Ausgaben, die ich brauche. Was ich bekomme, sind Fundstellen von *.html, aber nichts aus den *.pdf-Dateien. Im Ordner -Pfad/Linux/Allgemein befinden sich 3 Ordner und 72 Files - 2 der Ordner sind *.html, der Rest sind *.pdf-Dateien. Ene davon heißt sogar 'grep.pdf, sonst sind da so Sachen wie 'The_Linux_Command_Line' von William E. Shotts - da sollten doch ein paar 'grep' oder 'find' - Fundstellen möglich sein?
'find ~/eBooks/Linux/Allgemein -iname '*.html' -o -iname '*.pdf' -exec grep -n grep {} \; >output.txt' - ergibt leere Datei output.txt
find ~/eBooks/Linux/Allgemein -iname '*.html' -o -iname '*.pdf' -exec grep -n find {} \; >output.txt - dito
find ~/eBooks/Linux/Allgemein -iname '*.pdf' -print0 | xargs -0 grep -n find >output.txt - dito
find ~/eBooks/Linux/Allgemein -iname '*.pdf' -o -iname '*.html' -print0 | xargs -0 grep -n find >output.txt - findet immerhin was in meinen *.html - Dateien...
Ich weiß nix mehr...
[oder?]
Das hier hab ich noch getestet: 'find ~/eBooks/Linux/Allgemein -iname '*.pdf' -exec grep -ln grep {} \;
Ausgabe:
Code: Alles auswählen
'/home/fradie/eBooks/Linux/Allgemein/Linux 2011.pdf
/home/fradie/eBooks/Linux/Allgemein/Linux fromScratch -7.3.pdf
/home/fradie/eBooks/Linux/Allgemein/grep.pdf
/home/fradie/eBooks/Linux/Allgemein/Linux from Scratch.pdf
/home/fradie/eBooks/Linux/Allgemein/LINUX - Installation, Konfiguration, Anwendung_noPW.pdf
/home/fradie/eBooks/Linux/Allgemein/SelfLinux-0.13.0-pdf/mplayer.pdf
Das hier 'find ~/eBooks/Linux/Allgemein -iname '*.pdf' -exec grep -n grep {} \;' dagegen lieferte dies:
(Ich sage vorher schonmal gute Nacht und danke schön! Ich musste die Ausgabe wg erlaubter 50.000 Zeichen etwas kürzen )
Code: Alles auswählen
<</Limits[(table.caption.671)(table.caption.970)]/Names[(table.caption.671)76 0 R (table.caption.677)74 0 R (table.caption.680)72 0 R (table.caption.684)70 0 R (table.caption.687)68 0 R (table.caption.690)66 0 R (table.caption.692)65 0 R (table.caption.694)63 0 R (table.caption.696)61 0 R (table.caption.70)59 0 R (table.caption.700)57 0 R (table.caption.702)55 0 R (table.caption.705)54 0 R (table.caption.707)52 0 R (table.caption.710)50 0 R (table.caption.712)48 0 R (table.caption.716)46 0 R (table.caption.719)44 0 R (table.caption.722)43 0 R (table.caption.724)41 0 R (table.caption.728)40 0 R (table.caption.730)38 0 R
[...]
R/Count -5/First 5575 0 R/Last 5569 0 R/Next 5556 0 R/Parent 5498 0 R/Prev 5578 0 R/Title(Teil 1 Einf\374hrung und I<</A 5582 0 R/Count -10/First 5580 0 R/Last 5497 0 R/Next 5482 0 R/Parent 5092 0 R/Prev 5587 0 R/Title(\376\377Inhaltsverzeichni<</A 5602 0 R/F 2/Next 5587 0 R/Parent 5092 0 R/Title(Linux 2011 - Debian, Fedora, openSUSE, Ubuntu - 10., \374berarbeitete und streamter/FlateDecode/Length 1564>>
Übereinstimmungen in Binärdatei /home/fradie/eBooks/Linux/Allgemein/Linux fromScratch -7.3.pdf.
Übereinstimmungen in Binärdatei /home/fradie/eBooks/Linux/Allgemein/grep.pdf.
4524:/A << /URI (http://www.gnu.org/software/grep/)
4535:/A << /URI (http://ftp.gnu.org/gnu/grep/grep-2.5.3.tar.bz2)
5564:/A << /URI (http://www.linuxfromscratch.org/patches/lfs/6.4/grep-2.5.3-debian_fixes-1.patch)
5575:/A << /URI (http://www.linuxfromscratch.org/patches/lfs/6.4/grep-2.5.3-upstream_fixes-1.patch)
Übereinstimmungen in Binärdatei /home/fradie/eBooks/Linux/Allgemein/LINUX - Installation, Konfiguration, Anwendung_noPW.pdf.
Übereinstimmungen in Binärdatei /home/fradie/eBooks/Linux/Allgemein/SelfLinux-0.13.0-pdf/mplayer.pdf.
Zuletzt geändert von fradie am 07.10.2013 23:09:32, insgesamt 1-mal geändert.
debian 3.10-2-686-pae #1 SMP Debian 3.10.7-1 (2013-08-17) i686 GNU/Linux
Re: Grep, ack-grep, find, sort, *.pdf
fradie hat geschrieben:find ~/eBooks/Linux/Allgemein -iname '*.pdf' -o -iname '*.html' -print0 | xargs -0 grep -n find >output.txt - findet immerhin was in meinen *.html - Dateien...
Code: Alles auswählen
find ~/eBooks/Linux/Allgemein -iname '*.pdf' -o -iname '*.html' -exec grep -n find {} + >output.txt
Re: Grep, ack-grep, find, sort, *.pdf
SOrry,
aber deinen Vorschlag mit dem '+' hatte ich auch getestet - mit dem Ergebnis, dass 'find' nur die *.html - Dateien durchsuchte ...
Danke trotzdem!
Dietrich
aber deinen Vorschlag mit dem '+' hatte ich auch getestet - mit dem Ergebnis, dass 'find' nur die *.html - Dateien durchsuchte ...
Danke trotzdem!
Dietrich
debian 3.10-2-686-pae #1 SMP Debian 3.10.7-1 (2013-08-17) i686 GNU/Linux
Re: Grep, ack-grep, find, sort, *.pdf
Und jetzt nochmal: PDF haben:
1. Keine Zeilen nur Positionen. => Es kann keine Zeilenangaben geben
2. Sind sie nicht im Klartext. => Man sollte nicht einfach mit grep drüber fahren.
Deswegen kam 23min nach Caes Vorschlag einer von mir der das Behebt und eben keine Zeilen angibt.
In dem war allerdings ein kleiner Fehler (statt einem l gab ich ein n mit.) Phineas verbesserte das weitere 14 Minuten späer. (Im übrigen noch sehr ellegant sodass der schneller läuft und sauberere Ergebnisse bringt als mein Ursprünglich gedachter.) Also hat es insgesammt nichteinmal eine halbe Stunde gedauert, bis ein sauberer Vorschlag da war.
Über 24h später fallen die Fehler das dann auch dem Fragesteller auf. Aber statt die Beiträge etwas genauer zu lesen wird einfach mal eine 10-Seitige Fehlermeldung gepostst.
Kann ja nciht sein, dass niemand den Befehl am stück postet und man auchnoch außerhalb der Code-blöcke lesen muss.
1. Keine Zeilen nur Positionen. => Es kann keine Zeilenangaben geben
2. Sind sie nicht im Klartext. => Man sollte nicht einfach mit grep drüber fahren.
Deswegen kam 23min nach Caes Vorschlag einer von mir der das Behebt und eben keine Zeilen angibt.
In dem war allerdings ein kleiner Fehler (statt einem l gab ich ein n mit.) Phineas verbesserte das weitere 14 Minuten späer. (Im übrigen noch sehr ellegant sodass der schneller läuft und sauberere Ergebnisse bringt als mein Ursprünglich gedachter.) Also hat es insgesammt nichteinmal eine halbe Stunde gedauert, bis ein sauberer Vorschlag da war.
Über 24h später fallen die Fehler das dann auch dem Fragesteller auf. Aber statt die Beiträge etwas genauer zu lesen wird einfach mal eine 10-Seitige Fehlermeldung gepostst.
Kann ja nciht sein, dass niemand den Befehl am stück postet und man auchnoch außerhalb der Code-blöcke lesen muss.
rot: Moderator wanne spricht, default: User wanne spricht.
Re: Grep, ack-grep, find, sort, *.pdf
Das ist auch kein Wunder, da die Oder-Verknüpfung die komplette Parameterliste zweiteilt. Entweder musst Du die Parameter auf beiden Seiten des Oders gleichsetzen oder Du musst das entsprechende Oder klammern:fradie hat geschrieben:SOrry,
aber deinen Vorschlag mit dem '+' hatte ich auch getestet - mit dem Ergebnis, dass 'find' nur die *.html - Dateien durchsuchte ...
Code: Alles auswählen
>$ find . -iname '*.pdf' | wc -l
192
>$ find . -iname '*.html' | wc -l
5645
>$ find . -iname '*.pdf' -o -iname '*.html' | wc -l
5837
>$ find . -iname '*.pdf' -o -iname '*.html' -print | wc -l
5645
>$ find . -iname '*.html' -o -iname '*.pdf' -print | wc -l
192
>$ find . \( -iname '*.pdf' -o -iname '*.html' \) -print | wc -l
5837
>$ find . -iname '*.pdf' -print -o -iname '*.html' -print | wc -l
5837
Re: Grep, ack-grep, find, sort, *.pdf
Gibt es tatsächlich: pdfgrepPhineas hat geschrieben:Oder ein spezielles "pdf-grep" nutzen (falls es so etwas gibt).
Re: Grep, ack-grep, find, sort, *.pdf
@ wanne:
sorry, hatte wohl 'n stack overflow - jetzt kapier ichs endlich.
@ tobo und phineas:
pdfgrep ist der Hammer! Klasse Tipp, thx.
Mit einem einfachen
pdfgrep -rnH '\<find\>' . war das Problem gelöst!
sorry, hatte wohl 'n stack overflow - jetzt kapier ichs endlich.
@ tobo und phineas:
pdfgrep ist der Hammer! Klasse Tipp, thx.
Mit einem einfachen
pdfgrep -rnH '\<find\>' . war das Problem gelöst!
debian 3.10-2-686-pae #1 SMP Debian 3.10.7-1 (2013-08-17) i686 GNU/Linux