[tatsächlich gelöst!] Dateien kopieren, wenn grep ein Wort entdecktg

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

[tatsächlich gelöst!] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von desputin » 11.06.2020 12:40:31

Hallo Ihr,

ich habe 1.000 html-Dateien, von denen ca. 400 das Wort "Annexion" beinhalten. Ich würde gerne diese 400 Seiten irgendwohin kopieren oder zu einer Datei verschmelzen, aber alle anderen 600 Dateien wegschmeißen/löschen.

Wie mach ich das mit grep?

Viele Grüße
desputin
Zuletzt geändert von desputin am 17.07.2020 13:23:09, insgesamt 4-mal geändert.
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

Benutzeravatar
Tintom
Moderator
Beiträge: 3033
Registriert: 14.04.2006 20:55:15
Wohnort: Göttingen

Re: Dateien kopieren, wenn grep ein Wort entdeckt

Beitrag von Tintom » 11.06.2020 13:20:58

Ich würde es mit dem Schalter -l probieren:
man grep hat geschrieben: -l, --files-with-matches
Suppress normal output; instead print the name of each input file from which output would normally have been printed. The
scanning will stop on the first match.
Ich würde gerne diese 400 Seiten irgendwohin kopieren
$ for i in `grep -l Annexion *`;do cp ${i} ${i}_annexion; done
aber alle anderen 600 Dateien wegschmeißen/löschen
$ for i in `grep -vl Annexion *`;do rm ${i}; done

Such' dir etwas aus :wink:

Benutzeravatar
Lord_Carlos
Beiträge: 5578
Registriert: 30.04.2006 17:58:52
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Dänemark

Re: Dateien kopieren, wenn grep ein Wort entdeckt

Beitrag von Lord_Carlos » 11.06.2020 13:23:19

Hast du schon selbst gesucht? Bei mir wird da sehr viel brauchbares ausgespuckt.

https://unix.stackexchange.com/a/297011
rep -rl --null --include '*.html' Annexion . | xargs -0r cp -t /path/to/dest

Code: Alles auswählen

╔═╗┬ ┬┌─┐┌┬┐┌─┐┌┬┐╔╦╗
╚═╗└┬┘└─┐ │ ├┤ │││ ║║
╚═╝ ┴ └─┘ ┴ └─┘┴ ┴═╩╝ rockt das Forum!

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: Dateien kopieren, wenn grep ein Wort entdeckt

Beitrag von desputin » 11.06.2020 13:29:28

Hallo Tintom,

super, vielen Dank. Das hat schon mal funktioniert mit dem Wort Annexion.
Allerdings habe ich gesehen, steht das Wort in einem Kontext von html-Zeichen, also in etwa so:

Code: Alles auswählen

"Kategorie">Annexion
Wenn ich das aber in Anführungsstriche schreibe, also so:

Code: Alles auswählen

for i in `grep -l ""Kategorie">Annexion" *`;do cp ${i} ${i}_Annexion; done
Dann kriege ich eine Fehlermeldung.... Wie kann diese Zeichenfolge inklusive Sonderzeichen dann korrekt in den Befehl einfügen?
Zuletzt geändert von desputin am 11.06.2020 14:39:03, insgesamt 1-mal geändert.
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: Dateien kopieren, wenn grep ein Wort entdeckt

Beitrag von desputin » 11.06.2020 13:50:29

Hallo Lord_Carlos,

danke, so scheint es potentiell auch zu gehen. Allerdings bekomme ich eine Fehlermeldung, wenn ich das hier eingebe:

Code: Alles auswählen

rep -rl --null --include '*.html' "Kategorie">Annexion" . | xargs -0r cp -t /home/user/Downloads/test/1/
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: Dateien kopieren, wenn grep ein Wort entdeckt

Beitrag von desputin » 11.06.2020 14:38:12

Update: Also so scheint es zu funktionieren:

Code: Alles auswählen

for i in `grep -l -F 'Kategorie">Annexion' *`;do cp ${i} ${i}_Annexion; done
Obwohl ich eine Fehlermeldung bekomme ("grep: 1: Ist ein Verzeichnis")


Danke Euch!
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Doch noch nicht ganz...

Beitrag von desputin » 08.07.2020 16:29:53

Hallo Ihr,
in dem Verzeichnis liegen 2 Mio. html-Dateien. Beim Befehl:

Code: Alles auswählen

for i in `grep -l -F 'Kategorie">Annexion' *`;do cp ${i} ${i}_Annexion; done
bekomme ich leider diese Fehlermeldung:

Code: Alles auswählen

-bash: /bin/grep: Die Argumentliste ist zu lang
Wißt Ihr, wie ich den Befehl umstellen kann, damit er klappt?

Viele Grüße desputin
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: [noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von heinz » 08.07.2020 17:13:51

Hallo desputin,

Du koenntest die gefundenen Dateien in eine Datei schreiben...
Ungetestet!

Code: Alles auswählen

grep -l -F 'Kategorie">Annexion' * >./alle_gefundenen_dateien.txt

while read
do
  cp "${REPLY}" "${REPLY}_Annexion"
done <./alle_gefundenen_dateien.txt
gruss, heinz

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: [noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von desputin » 08.07.2020 18:03:09

Ok, danke! Ich werde mal testen und dann berichten.
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: [noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von desputin » 08.07.2020 18:10:05

Hm, scheint noch nicht funktioniert zu haben. Ich bekomme nur:

1. Eine Datei alle_gefundenen_dateien.txt in der der Name des Scripts drin steht filtern-script.sh
2. Eine Datei die wie mein Script heißt: filtern-script.sh_Annexion

Sonst passiert leider nichts.
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: [noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von heinz » 08.07.2020 20:16:08

desputin hat geschrieben: ↑ zum Beitrag ↑
08.07.2020 18:10:05
1. Eine Datei alle_gefundenen_dateien.txt in der der Name des Scripts drin steht filtern-script.sh
2. Eine Datei die wie mein Script heißt: filtern-script.sh_Annexion
Deiese Ergebnis bekommst Du mMn., wenn Dein Script nicht in dem Verzeichnis ausgefuehrt wird, wo die .html dateien liegen...

Gruss,
heinz

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: [noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von desputin » 09.07.2020 12:47:35

Hallo Heinz,
alles klar, danke für den Hinweis. Jetzt scheint es zu klappen!
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: [noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von desputin » 09.07.2020 13:16:39

Hm, doch wieder nicht geklappt :(

Code: Alles auswählen

./filtern-script.sh: Zeile 1: /bin/grep: Die Argumentliste ist zu lang
Wie viele Dateien kann grep denn? Also wo liegt die Obergrenze? Kann ich mit einem mv-Befehl irgendwie sagen, daß er 10% aller Dateien in ein anderes Verzeichnis kopieren soll? Dann würde ich als Workaround 10 Verzeichnisse machen und das Script zehn Mal ausführen. Wäre Wahnsinn, aber scheint ja nicht anders zu gehen. Oder?

@Lord_Carlos mit Deinem Befehl habe ich es auch probiert und da kommt keine Fehlermeldung. Also so:

Code: Alles auswählen

grep -rl --null --include '*.html' Annexion . | xargs -0r cp -t /output/verzeichnis
Allerdings scheint mir die Zahl der Ergebnisse viel zu gering zu sein. Zweifle also daran, ob es wirklich geklappt hat. Müßte das vielleicht doch noch mal mit find probieren...
Zuletzt geändert von desputin am 09.07.2020 14:18:14, insgesamt 1-mal geändert.
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

tobo
Beiträge: 1996
Registriert: 10.12.2008 10:51:41

Re: [immer noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von tobo » 09.07.2020 14:14:03

Das Problem ist, dass weiterhin alle Dateien, als Parameter, hinter dem grep stehen. Entweder kümmert man sich darum, dass diese Anzahl automatisch begrenzt wird (find) oder man ruft grep nur mit einer Datei auf (womöglich langsam in einer for-Schleife):

Code: Alles auswählen

##1.Variante:
find DIR -type f -name '*.html' -exec grep -lF 'Kategorie">Annexion' {} + > alle_gefundenen_dateien.txt

##2.Variante:
>alle_gefundenen_dateien.txt
for i in DIR/*.html; do grep -lF 'Kategorie">Annexion' "$i" >> alle_gefundenen_dateien.txt; done
DIR ist dabei entsprechend anzupassen bzw. durch . zu ersetzen. Kannst ja mal beides auf Funktionalität und Zeitverhalten testen!?

PS: Deine Dateivermehrung ist beeindruckend!

EDIT: Parameter im for ergänzt.
Zuletzt geändert von tobo am 09.07.2020 15:38:13, insgesamt 1-mal geändert.

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: [immer noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von desputin » 09.07.2020 14:19:29

Hallo Tobo, danke ich teste mal. Ja 2 Mio. Dateien, weil ich nicht wußte, in welchen Urls überall sich das Suchwort versteckt und in welchen nicht. Ich teste mal Deinen Find-Befehl.
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

tobo
Beiträge: 1996
Registriert: 10.12.2008 10:51:41

Re: [immer noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von tobo » 09.07.2020 15:40:15

Habe die for-Schleife mal noch edititiert, damit sie auch was tut!? Laufzeitverhalten der beiden Fälle wäre interessant...

Benutzeravatar
desputin
Beiträge: 1298
Registriert: 24.04.2015 17:16:34

Re: [immer noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von desputin » 16.07.2020 13:17:53

Ich hab's gerade angeworfen. Dauert schon eine ganze Weile. Sage morgen oder nächste Woche mal, wie es so steht...


@tobo: Also der Find-Befehl ist jetzt durch. Lief ca. 3,5 Stunden geschätzt auf einer recht neuen Maschine (aber soweit ich sehe nur auf einem Thread oder Core). Durchsucht wurden ca. 4 Mio. Dateien.
Der for.... Befehl war nach über 24 Stunden noch nicht fertig, habe ihn daher abgebrochen.

Die Lösung lautet also für mich:

Code: Alles auswählen

find DIR -type f -name '*.html' -exec grep -lF 'Kategorie">Annexion' {} + > alle_gefundenen_dateien.txt
Danke noch mal!
https://www.daswirdmanjawohlnochsagenduerfen.de
https://www.neoliberalyse.de - Über die Ökonomisierung aller Lebensbereiche. |

tobo
Beiträge: 1996
Registriert: 10.12.2008 10:51:41

Re: [immer noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von tobo » 19.07.2020 01:10:27

desputin hat geschrieben: ↑ zum Beitrag ↑
16.07.2020 13:17:53
Ich hab's gerade angeworfen. Dauert schon eine ganze Weile. Sage morgen oder nächste Woche mal, wie es so steht...
Ein neuer Beitrag (anstatt edit) wäre besser gewesen, aber trotzdem danke für die Rückmeldung!
Der for.... Befehl war nach über 24 Stunden noch nicht fertig, habe ihn daher abgebrochen.
Für jede Datei ein grep-Prozess. Ja, war eigentlich aussichtslos...
Die Lösung lautet also für mich:

Code: Alles auswählen

find DIR -type f -name '*.html' -exec grep -lF 'Kategorie">Annexion' {} + > alle_gefundenen_dateien.txt
Im Eigeninteresse (und nach Wichtigkeit) würde ich folgende Variante noch mit deiner vergleichen. Vermutlich liefern beide eine gleiche Datei "alle_gefundenen_dateien.txt" und vermutlich sollte man das Verhalten auch direkt wissen!? Egal, du kannst das 3,5 Stunden laufen lassen und vergleichen oder du überprüfst, sobald die ersten Dateieinträge eintrudeln. Wenn die gleich sind, dann kannst du abbrechen...

Code: Alles auswählen

>alle_gefundenen_dateien.txt
find DIR -type f -name '*.html' -exec grep -lF 'Kategorie">Annexion' {} + >> alle_gefundenen_dateien.txt

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [immer noch nicht ganz gelöst] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von Meillo » 19.07.2020 09:34:25

tobo hat geschrieben: ↑ zum Beitrag ↑
19.07.2020 01:10:27
desputin hat geschrieben: ↑ zum Beitrag ↑
16.07.2020 13:17:53
Die Lösung lautet also für mich:

Code: Alles auswählen

find DIR -type f -name '*.html' -exec grep -lF 'Kategorie">Annexion' {} + > alle_gefundenen_dateien.txt
Im Eigeninteresse (und nach Wichtigkeit) würde ich folgende Variante noch mit deiner vergleichen. Vermutlich liefern beide eine gleiche Datei "alle_gefundenen_dateien.txt" und vermutlich sollte man das Verhalten auch direkt wissen!? Egal, du kannst das 3,5 Stunden laufen lassen und vergleichen oder du überprüfst, sobald die ersten Dateieinträge eintrudeln. Wenn die gleich sind, dann kannst du abbrechen...

Code: Alles auswählen

>alle_gefundenen_dateien.txt
find DIR -type f -name '*.html' -exec grep -lF 'Kategorie">Annexion' {} + >> alle_gefundenen_dateien.txt
@tobo: Kannst du deinen Gedankengang hier erklaeren. Warum diese Variante?
Use ed once in a while!

tobo
Beiträge: 1996
Registriert: 10.12.2008 10:51:41

Re: [tatsächlich gelöst!] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von tobo » 19.07.2020 11:24:18

Der Unterschied ist ja nur, dass an die Datei angehängt wird, statt sie neu zuschreiben (>>Datei statt >Datei). Die Überlegung ist, dass die (inzwischen) 4 Millionen Dateien natürlich zu lang für eine einzige Befehlszeile sind und somit die Dateien in meheren Parameterlisten nacheinander übergeben werden müssen. Jetzt ist die Frage, wie das Verhalten von find (mit dem Paramter + anstatt \;) ist - sprich, findet dort "automatisch" ein Anhängen an die Datei statt und ignoriert find damit das Überschreiben der Datei oder wird (pro generierter Parameterliste) überschrieben und damit die zuvor gefundenden Ergebnisse vernichtet?! Mit dem find-Parameter + (anstatt \;) ist das dann auch noch ein Mischmasch an Zuständigkeit für eben diese Parameterlisten, die mir nicht ganz klar ist. Kurz, Sonderfälle besser selbst prüfen, statt sich auf Aussagen anderer zu verlassen...

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [tatsächlich gelöst!] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von Meillo » 19.07.2020 11:42:30

tobo hat geschrieben: ↑ zum Beitrag ↑
19.07.2020 11:24:18
Der Unterschied ist ja nur, dass an die Datei angehängt wird, statt sie neu zuschreiben (>>Datei statt >Datei). Die Überlegung ist, dass die (inzwischen) 4 Millionen Dateien natürlich zu lang für eine einzige Befehlszeile sind und somit die Dateien in meheren Parameterlisten nacheinander übergeben werden müssen. Jetzt ist die Frage, wie das Verhalten von find (mit dem Paramter + anstatt \;) ist - sprich, findet dort "automatisch" ein Anhängen an die Datei statt und ignoriert find damit das Überschreiben der Datei oder wird (pro generierter Parameterliste) überschrieben und damit die zuvor gefundenden Ergebnisse vernichtet?! Mit dem find-Parameter + (anstatt \;) ist das dann auch noch ein Mischmasch an Zuständigkeit für eben diese Parameterlisten, die mir nicht ganz klar ist. Kurz, Sonderfälle besser selbst prüfen, statt sich auf Aussagen anderer zu verlassen...
Die Frage kann ich dir beantworten. Du denkst zu kompliziert. ;-) Find(1) hat mit den Ausgabeumleitungen gar nichts zu tun. Die uebernimmt die Shell bevor find(1) oder seine exec-Befehle auch nur gestartet sind. Egal was find(1) oder seine Unterbefehle auf stdout ausgeben, es landet alles in der Datei. Nur die Reihenfolge der Zeilen darin kann variieren, falls die exec-Befehle in unvorhersagbarer Reihenfolge oder parallel arbeiten.
Use ed once in a while!

tobo
Beiträge: 1996
Registriert: 10.12.2008 10:51:41

Re: [tatsächlich gelöst!] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von tobo » 19.07.2020 12:08:10

Ja, in etwa so habe ich mir das auch gedacht, war mit allerdings nicht sicher. Danke für die Informationen, Meillo!
Bedeutet also, dass die beiden Dateien verschieden sein können (obwohl nur 1 Thread), allerdings dieselbe Anzahl (wc -l Datei) an Zeilen haben werden/sollten.

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [tatsächlich gelöst!] Dateien kopieren, wenn grep ein Wort entdecktg

Beitrag von Meillo » 19.07.2020 13:48:08

tobo hat geschrieben: ↑ zum Beitrag ↑
19.07.2020 12:08:10
Bedeutet also, dass die beiden Dateien verschieden sein können (obwohl nur 1 Thread), allerdings dieselbe Anzahl (wc -l Datei) an Zeilen haben werden/sollten.
Wenn man sie nachtraeglich sortiert, sind sie identisch. D.h. sie enthalten die gleichen Zeilen.

Mehr noch: Wenn find(1) die Unterbefehle nacheinander ausfuehrt und diese die Dateinamen in der gleichen Reihenfolge uebergeben bekommen (was bei einem Thread sicherlich gegeben ist), dann kommen aus den grep(1)s die Ausgaben auch in der gleichen Reihenfolge raus. Das ist durch die grep(1)-Implementierung gegeben.

Die Dateien sind aber in beiden Faellen auch deshalb gleich, weil die Shell fuer die Dateiumleitung jeweils genau einen open(2) macht, entweder mit `O_APPEND' oder ohne. Dieser Dateidescriptor wird dann mittels dup2(2) auf die Nummer 1 (stdout) gelegt und so an find(1) uebergeben. Der ihn wiederum an seine Kindprozesse kopiert. Ob die Datei mit `O_APPEND' geoeffnet worden ist oder nicht, macht hierfuer dann keine Unterschiede mehr. (Sie wird nicht mehrmals geoeffnet!)

Wenn zwei Aufrufe des find(1)-Befehls garantiert die gleiche Ausgabe erzeugen, dann tun sie es auch wenn man die Umleitung aendert.
Use ed once in a while!

Antworten