staging.inyokaproject.org

Einen String zeilenweise in einer Textdatei suchen

Status: Gelöst | Ubuntu-Version: Server 16.04 (Xenial Xerus)
Antworten |

bigchris

Anmeldungsdatum:
1. November 2008

Beiträge: 182

Ich habe Srings in dieser Art in einer Datei stehen:

5C4979227529
 E8377AB7EE6B
 0896D741527D
 3481C42C3745
 944A0CE82FD3
 000E8F331F04
 0896D7E771CE
 BC8CCDF60AD8
 5C497971D760
 D42122D33A13
 80717AEA4BFB
 000E8F19FE63
 1883BFBBE1FE
 346BD344E941
 80717AEA4BFD
 D42122D33A15
 000E8F19FE65
 000E8F331F05
 000E8F331F06
 000E8F331F03
 5CDC9601CFF2
 E8377AB7EE6C
 3481C4FF953D
 4C09D4294087
 FA8FCA7D1779
 246511B06A23
 3481C4FF953E
 A8D3F7AFE4F2
 3481C4FF953D
 4C09D4294087
 FA8FCA7D1779
 246511B06A23
 3481C4FF953E
 A8D3F7AFE4F2

Nach diesen Strings würde ich gerne ich einer Textdatei suchen lassen und wenn ein String dort vorkommt diese Zeile ausgeben lassen. Wie kann ich das machen? Manuell würde ich grep benutzen, so in der Art:

cat /einVerzeichnis/eineDatei | grep 3481C4FF953D >> ausgabe

Doch wie mache ich so was automatisiert? Mittels einer Schleife?

Gruß Christian

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Wie viele Suchstrings hast du denn? Solange das halbwegs überschaubar bleibt, kann man grep einfach nach mit \| abgetrennten Alternativen suchen lassen:

1
grep "3481C4FF953D\|944A0CE82FD3\|D42122D33A13" /einVerzeichnis/eineDatei >> ausgabe

Den Suchstring für grep kann man auch automatisiert aus einer Datei erstellen lassen:

1
2
3
readarray -t searches < datei_mit_einem_suchstring_pro_zeile
search_string=$(printf "%s\|" ${searches[@]})
grep "$search_string" /einVerzeichnis/eineDatei >> ausgabe

Alternativ könnte man z.B. auch eine andere Skriptsprache wie Python3 bemühen:

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
import sys

with open(sys.argv[1]) as search_file:
    searches = search_file.readlines()
with open(sys.argv[2]) as data:
    for line in data:
        if any((s for s in searches if s.strip() in line)):
            print(line, end='')

Das würde man dann mit der Datei, die die gesuchten Wörter enthält und der Datei, die durchsucht werden soll als Argumente aufrufen:

python3 psearch.py datei_mit_einem_suchstring_pro_zeile /einVerzeichnis/eineDatei >> ausgabe

apt-ghetto

Anmeldungsdatum:
3. Juni 2014

Beiträge: 2943

Mit der Bash könnte das so aussehen:

1
2
3
4
5
#!/bin/bash

while IFS= read -r; do
    grep "$REPLY" textdatei.txt >> ausgabedatei.txt
done < stringsZumVergleich.txt

Dein cat ist übrigens unnötig, da du die Datei grep auch direkt angeben kannst.

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7795

Entweder Schleife...

for string in $(<strings.txt)
do
    grep "$string" /einVerzeichnis/eineDatei >> ausgabe
done

...oder einen regulären Ausdruck bauen.

regex=$(printf "%s|" $(<strings.txt))
regex="(${regex%|})"
grep -E "$regex" /einVerzeichnis/eineDatei >> ausgabe

Wobei das davon ausgeht daß die Strings wie in deinem Beispiel keine Sonderzeichen haben...

xuniL123

Anmeldungsdatum:
5. August 2012

Beiträge: 293

grep -f datei_mit_suchstrings datei_in_der_gesucht_wird

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Das Schnellste wäre wohl, die Suchmuster in einem Array zu speichern, und dann mit einer Schleife die Suchmuster alle für jede Zeile durch zu gehen.

Geht im Prinzip mit jeder Sprache die Reguläre Ausdrücke kennt ... mit awk könnte es z.B. so aussehen:

track@track:~$ echo '5C4979227529
>  E8377AB7EE6B
>  0896D741527D
>  3481C42C3745'  > muster.txt
track@track:~$ echo ' stimmt nur halb: E8377AB7EE6
> hat nix zu sagen
> nein das0896D741527Dversteckt sich.'  > beispiel.txt
track@track~$ awk 'ARGIND==1 {m[FNR]=$1} ARGIND==2 {for(i in m) if($0 ~ m[i]) {print; next}}'  muster.txt  beispiel.txt
nein das0896D741527Dversteckt sich. 

oder das selbe nochmal, als Skript geschrieben und kommentiert:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/usr/bin/awk -f

ARGIND==1 {                          # bei der 1. Datei:
        m[FNR]=$1  }                 # speichere das 1. Wort im Array (beliebiger Index, hier einfach die Zeilennummer)

ARGIND==2 {                          # bei der 2. Datei:
        for(i in m)                  # gehe alle Indices durch
            if($0 ~ m[i]) {          # und wenn das Muster passt:
                print;               # drucke
                next  }              # und nimm sofort die nächste Zeile (spart Zeit und verhindert ggf. doppeltes Drucken)
        }

... so mal als Lösungsskizze.

LG,

track

p.s.:
die Lösung von xuniL123 mit grep -f ist ja genial einfach ! (die hatte ich gar nicht auf dem Schirm)

Mit Deinem Beispiel gibt es dabei nur einen Haken: die Leerzeichen am Zeilenanfang gehöre dann mit zum Suchmuster !
Das heißt: mit meinem Beispiel fände er nichts, weil dort das Leerzeichen davor fehlt.
→ kommt jetzt darauf an, wie das gemeint ist: ob das Leerzeichen gewollt ist, oder ein Kopierfehler oder sowas ...

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7795

xuniL123 schrieb:

grep -f datei_mit_suchstrings datei_in_der_gesucht_wird

Beste Antwort 😀 Ich nutze fgrep einfach viel zu selten, denkt man nicht mal mehr dran.

Falls unnötiger Whitespace in der Datei ist wird man so los:

printf "%s\n" $(<strings.txt) > suchstrings.txt

bigchris

(Themenstarter)

Anmeldungsdatum:
1. November 2008

Beiträge: 182

Boah, vielen Dank! NAch so kurzer Zeit so viele Antworten mit Ansätzen!

Ich mache mich mal gleich ans verstehen und umsetzen...

Danke, danke, danke

bigchris

(Themenstarter)

Anmeldungsdatum:
1. November 2008

Beiträge: 182

Ich nutze fgrep einfach viel zu selten, denkt man nicht mal mehr dran.

grep -f ist nicht gleich fgrep ☺

Hat aber funktioniert, danke noch mal an alle.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

bigchris schrieb:

grep -f ist nicht gleich fgrep ☺

In diesem Falle sollte man fgrep -f suchdatei nutzen, da Du keine regulären Ausdrücke in der Datei hast.

Antworten |