Textfile mit Wort vergleichen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
wolli112
Beiträge: 42
Registriert: 30.12.2009 21:09:32

Textfile mit Wort vergleichen

Beitrag von wolli112 » 01.04.2014 07:34:59

Hallo,

ich habe ein Problem, und finde im Forum nichts dazu, bzw. ich stell mich mit der Suche vielleicht nur an ...

Ich habe ein Textfile und möchte es mit einem Wort vergleichen. Wie kann ich das in einem Skript umsetzen?

Am besten mit eine if, damit ich geich etwas einleiten kann wenn ein anderes Wort drin vorkommt.

Hoffe Ihr könnt mir helfen, bzw. zeigen wo was dazu steht!

Danke

wolli112

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Textfile mit Wort vergleichen

Beitrag von rendegast » 01.04.2014 07:59:41

Code: Alles auswählen

grep [optionen] wort datei && { mache was; }
?
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

wolli112
Beiträge: 42
Registriert: 30.12.2009 21:09:32

Re: Textfile mit Wort vergleichen

Beitrag von wolli112 » 01.04.2014 08:48:07

Danke,

das vergleicht mir mit einem bekanntwn WORT und macht was wenn es drin vorkommt,
nur ich suche etwas wenn ein unbekanntes WORT vorkommt!

Ich vermute mal der Weg ist ähnlich

Liffi
Beiträge: 2306
Registriert: 02.10.2004 01:33:05

Re: Textfile mit Wort vergleichen

Beitrag von Liffi » 01.04.2014 08:53:37

Mir ist nicht ganz klar, was du mit unbekanntem Wort meinst. Kannst du vielleicht ein einfaches Beispiel geben?
grep -v schließt ein bekanntes Wort aus, vielleicht hilft dir das schon.

Benutzeravatar
CH777
Beiträge: 1464
Registriert: 27.05.2008 16:37:17

Re: Textfile mit Wort vergleichen

Beitrag von CH777 » 01.04.2014 09:02:13

Möchtest du vielleicht zwei Textdateien vergleichen?

Code: Alles auswählen

diff DATEI1 DATEI2
Das würde dir die Unterschiede zwischen den Dateien ausgeben.

wolli112
Beiträge: 42
Registriert: 30.12.2009 21:09:32

Re: Textfile mit Wort vergleichen

Beitrag von wolli112 » 01.04.2014 09:07:43

Beispiel:

Ich schreibe automatisiert in eine Datei Wörter, in der Regel immer das gleiche.

TEST
TEST
TEST
TEST
TEST

Ich möchte diese Datei dann überprüfen ob nur TEST enthalten ist, und wenn nicht dann soll eine Aktion folgen!

Liffi
Beiträge: 2306
Registriert: 02.10.2004 01:33:05

Re: Textfile mit Wort vergleichen

Beitrag von Liffi » 01.04.2014 09:11:35

wolli112 hat geschrieben:Beispiel:

Ich schreibe automatisiert in eine Datei Wörter, in der Regel immer das gleiche.

TEST
TEST
TEST
TEST
TEST

Ich möchte diese Datei dann überprüfen ob nur TEST enthalten ist, und wenn nicht dann soll eine Aktion folgen!

Code: Alles auswählen

grep -v '^TEST$' datei && echo 'was anderes gefunden'

wolli112
Beiträge: 42
Registriert: 30.12.2009 21:09:32

Re: Textfile mit Wort vergleichen

Beitrag von wolli112 » 01.04.2014 09:18:19

Das funktioniert!

Jetzt muß ich es nur noch in mein Script basten!

Danke

Liffi
Beiträge: 2306
Registriert: 02.10.2004 01:33:05

Re: Textfile mit Wort vergleichen

Beitrag von Liffi » 01.04.2014 09:26:02

Vielleicht noch eine kleine Erklärung dazu: Ich suche mit einem regulärem Ausdruck nach Zeilen, die ausschließlich aus 'TEST' bestehen, ' TEST' wäre schon kaputt (Leerzeichen am Anfang). '^' bedeutet Anfang der Zeile, '$' das Ende.

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Textfile mit Wort vergleichen

Beitrag von rendegast » 01.04.2014 10:18:11

Anmerkung
zu einer "falschen" Verwendung von grep.

Es geht um ein gespiegeltes Verzeichnis (~1000 Dateien),
nach dem Abgleichen sollen obsolete Dateien gelöscht werden.

Code: Alles auswählen

#TO_DELETE="$(ls -1 $ACTIONDIR | grep -v -i -f $ACTIONDIR/.listing_awk)"
TO_DELETE="$(for i in $(ls -1 ${ACTIONDIR} ); do grep -q -i $i ${ACTIONDIR}/.listing_awk || echo $i ; done)"
Das erste elegante 'grep -f' braucht 6min und komplettes 768MB RAM,
das zweite for-Konstrukt nur 30sec, RAM nicht erwähnenswert.

Eine solche Verwendung findet sich auch im Linux-Zweig des
ct-update resp. wsus-offline-update, Bsp.

Code: Alles auswählen

    grep -F -i -v -f ../temp/tmpExcludeList-${sys}.txt ../temp/tmpUrls-${OS_sys}-${lang}.txt > ../temp/ValidUrls-${sys}-${lang}.txt
Der Grund, warum diese nette Anwendung (zumindest früher) urig lange herumrödelte.
EDIT Die Verzögerung wurde durch Verwendung des Parameters '-F' weitestgehend entfernt,
die verbliebenen "langsamen" 'grep -f'-Suchen fallen nicht mehr ins Gewicht.
Zuletzt geändert von rendegast am 01.04.2014 16:53:30, insgesamt 4-mal geändert.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

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

Re: Textfile mit Wort vergleichen

Beitrag von Meillo » 01.04.2014 11:55:23

rendegast hat geschrieben:Anmerkung
zu einer "falschen" Verwendung von grep.
Danke fuer den Hinweis. Das ist ein schoenes Beispiel einer in diesem Fall unguenstigen Art der Verwendung von grep.
Use ed once in a while!

Benutzeravatar
hikaru
Moderator
Beiträge: 13585
Registriert: 09.04.2008 12:48:59

Re: Textfile mit Wort vergleichen

Beitrag von hikaru » 01.04.2014 12:14:10

rendegast hat geschrieben:

Code: Alles auswählen

#TO_DELETE="$(ls -1 $ACTIONDIR | grep -v -i -f $ACTIONDIR/.listing_awk)"
TO_DELETE="$(for i in $(ls -1 ${ACTIONDIR} ); do grep -q -i $i ${ACTIONDIR}/.listing_awk || echo $i ; done)"
Das erste elegante 'grep -f' braucht 6min und komplettes 768MB RAM,
das zweite for-Konstrukt nur 30sec, RAM nicht erwähnenswert.
Könnte bitte jemand erklären wo der eklatante Unterschied herkommt?

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

Re: Textfile mit Wort vergleichen

Beitrag von Meillo » 01.04.2014 14:54:22

hikaru hat geschrieben:
rendegast hat geschrieben:

Code: Alles auswählen

#TO_DELETE="$(ls -1 $ACTIONDIR | grep -v -i -f $ACTIONDIR/.listing_awk)"
TO_DELETE="$(for i in $(ls -1 ${ACTIONDIR} ); do grep -q -i $i ${ACTIONDIR}/.listing_awk || echo $i ; done)"
Das erste elegante 'grep -f' braucht 6min und komplettes 768MB RAM,
das zweite for-Konstrukt nur 30sec, RAM nicht erwähnenswert.
Könnte bitte jemand erklären wo der eklatante Unterschied herkommt?
Zwei Gedanken dazu:

Im ersten Fall vergleicht grep alle Dateinamen (auf stdin) mit vielen Strings in `.listing_awk' (also n:m). Im zweiten Fall vergleichen ganz viele greps hintereinander je einen Dateinamen mit den Zeile in `.listing_awk' (also n mal 1:m). (Der Tausch der beiden Datenquellen funktioniert nur weil `-f' verwendet wird.)

Im ersten Fall wird `-i' auf alle Zeilen in `.listing_awk' angewendet. Im zweiten Fall wird `-i' jeweils auf den einzelnen Dateinamen angewendet. (Wie sind denn die Laufzeiten wenn man `-i' weglaesst?)
Use ed once in a while!

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: Textfile mit Wort vergleichen

Beitrag von rendegast » 01.04.2014 16:43:38

Meillo hat geschrieben: (Wie sind denn die Laufzeiten wenn man `-i' weglaesst?)
Kopiert auf einen etwas flotteren Rechner mit mehr RAM

Code: Alles auswählen

# time { ls -1 MultiData | grep -v -f MultiData/.listing_awk ; }
real    0m56.220s
user    0m55.640s
sys     0m0.508s
Ob mit oder ohne '-i' ist dabei egal.
Bei der for-Variante jedoch

Code: Alles auswählen

# time { for i in $(ls -1 MultiData); do grep -i -q "$i" MultiData/.listing_awk || echo "$i"; done; }
real    0m7.762s
user    0m4.368s
sys     0m0.648s

# time { for i in $(ls -1 MultiData); do grep -q "$i" MultiData/.listing_awk || echo "$i"; done; }
real    0m2.529s
user    0m0.196s
sys     0m0.416s
(Ich bleibe aber bei der Variante mit '-i', da ich dem Server resp. dessen Admins nicht so recht traue)

Flotteste Variante

Code: Alles auswählen

# time { ls -1 MultiData | grep -F -v -i -f MultiData/.listing_awk ; }
real    0m0.026s
user    0m0.020s
sys     0m0.004s
Boah, ey!



Meillo hat geschrieben: (Der Tausch der beiden Datenquellen funktioniert nur weil `-f' verwendet wird.)
und beide Datenquellen selbigen Formats/Inhalts sind.
(".listing"->".listing_awk" wurde dahingehend umgeformt)

In oben angesprochenem WSUS ginge die Vertauschung nicht so leicht,
da zBsp. im einen
...
http://_lange_lange_url_KB1234567_......
...
und im pattern-File nur
...
KB1234567
....
steht.





--------------
Nebenbei, 'ls -1' <-> 'ls' gibt wohl nur auf der shell einen Unterschied (readline-Krimskrams, pager, w.w.i.),
in der pipe ist beides identisch:

Code: Alles auswählen

# ls -1 | cat -A
MultiData$
test.bash$
test.sh$

# ls | cat -A
MultiData$
test.bash$
test.sh$
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

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

Re: Textfile mit Wort vergleichen

Beitrag von Meillo » 02.04.2014 09:45:55

rendegast hat geschrieben: Flotteste Variante

Code: Alles auswählen

# time { ls -1 MultiData | grep -F -v -i -f MultiData/.listing_awk ; }
real    0m0.026s
user    0m0.020s
sys     0m0.004s
Boah, ey!
Fixe Strings bringen immer sehr grosse Geschwindigkeitsvorteile.

Nebenbei, 'ls -1' <-> 'ls' gibt wohl nur auf der shell einen Unterschied (readline-Krimskrams, pager, w.w.i.),
in der pipe ist beides identisch:
ls(1) schaut ob stdout an einem Terminal haengt. Nur in dem Fall macht es die Ausgabe in Spalten. `ls -1' macht demnach nur dann einen Unterschied, wenn die Ausgabe auf's Terminal geht.

Bei Plan 9 haben sie uebrigens diese ``Unschoenheit'' (d.h., dass sich ein Programm je nach Umgebung unterschiedlich verhaelt) eliminiert. Da gibt es ls(1), das `ls -1' entspricht, und lc(1), das etwa `ls | column' entspricht.
Use ed once in a while!

Antworten