PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bash Grep Wörter aus Variable suchen



Kasashii
21.02.19, 08:56
Hallo,

ich habe momentan ein kleines Problem.
Ich lese aus einer Datei mehrere Hundert Zeilen in eine Variable ein, was auch wunderbar funktioniert. Jetzt muss ich mit dieser Variable in vielen Dateien nach den Strings suchen. Teilweise funktioniert das wunderbar, teilweise überhaupt nicht.

in der testdatei1.csv stehen bspw. AandE und America Sports drin. Wenn ich jetzt in der Datei danach suche findet er nur America Sports obwohl der andere String auch enthalten ist

Inhalt test.txt
<programme start="20190222200000 -0300" stop="20190222203000 -0300" channel="America Sports [ARG]">
<programme start="20190221114000 -0300" stop="20190221120500 -0300" channel="AandE [ARG]">

Da ist für mich kein wirklicher Unterschied zwischen den beiden Zeilen. Wenn ich jetzt allerdings hinter das AandE in der Variable noch irgendeinen weiteren Buchstaben oder ein Leerzeichen setze findet er diese Zeile

So suche ich nach den Wörtern



while read -r channelvariable; do

grep -m 5 -w "$channelvariable" $pfad/test.txt

done < "$pfad/testdatei1.csv"



Und falls ich ohne Variable, also einfach mit grep AandE $pfad/test.txt, danach suche findet er die auch alle.

Zudem bräuchte ich eine Option mit der ich America Sports als einen zusammengehörenden String ansehen könnte. Ich würde mit dem Befehl auch Ergebnisse bekommen mit
<programme start="20190222200000 -0300" stop="20190222203000 -0300" channel="America Film [ARG]">

Ich hoffe das ist ansatzweise verständlich und ihr könnt mir weiterhelfen

fork
21.02.19, 09:10
Grundsätzlich sieht das jetzt mal wie eine XML-Datei aus. Die würde ich bevorzugt mit xml-tools bearbeiten(xmlstarlet oder xmllint).

Wenn ich mal annehme, dass die XML-Datei so aussieht(Also valides xml aus dem Brocken, denn Du gezeigt hast):



<xml>
<programme start="20190222200000 -0300" stop="20190222203000 -0300" channel="America Sports [ARG]" />
<programme start="20190221114000 -0300" stop="20190221120500 -0300" channel="AandE [ARG]" />
</xml>


Dann hole ich mir die Channel-Attribute so heraus:



xmlstarlet sel -t -v "//programme/@channel" t.xml

# Ausgabe:

America Sports [ARG]
AandE [ARG]


Kannst Du mal eine komplette Testdatei als Anhang bereitstellen(ggf. anonymisiert)?
Bitte auch die Datei testdatei1.csv mal zeigen.

@Moderation: Könnt Ihr bitte mal die kaputten Umlaute korrigieren?

marce
21.02.19, 09:23
Was willst Du denn genau erreichen und was soll am Ender herauskommen?

Was spricht dagegen, die Suchstrings aus dem File direkt als Patterliste zu übergeben?
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. The empty file contains zero patterns, and therefore
matches nothing. (-f is specified by POSIX.)

Kasashii
21.02.19, 09:30
Danke schonmal für die Antwort.
An xml-tools habe ich gar nicht dran gedacht

Ich würde dir gerne die Datei als Anhang hinterlegen aber irgendwas hat die Seite wohl dagegen.


<?xml version="1.0" encoding="UTF-8"?>
<tv generator-info-name="WebGrab+Plus/w MDB &amp; REX Postprocess -- version V2.0 -- Jan van Straaten" generator-info-url="http://www.webgrabplus.com">
<channel id="America Sports [ARG]">
<display-name lang="es">America Sports [ARG]</display-name>
<icon src="http://181.30.4.186/buscador/img/Logos/183173.gif" />
<url>http://www.reportvMulti.com.ar</url>
</channel>
<channel id="AandE [ARG]">
<display-name lang="es">AandE [ARG]</display-name>
<icon src="http://181.30.4.186/buscador/img/Logos/191213.gif" />
<url>http://www.reportvMulti.com.ar</url>
</channel>
<programme start="20190222073000 -0300" stop="20190222080000 -0300" channel="America Sports [ARG]">
<title lang="es">Rafaelinos por el mundo</title>
<desc lang="es">Disfruta, conoce e imagina un impresionante recorrido por diferentes rutas turísticas que te conducirán a los lugares más concurridos y visitados del mundo(n)</desc>
<date>2014</date>
<category lang="es">Viajes</category>
<icon src="https://www.reportv.com.ar/buscador/img/Programas/3201859.jpg" />
<country>Argentina</country>
</programme>
<programme start="20190222110000 -0300" stop="20190222113000 -0300" channel="America Sports [ARG]">
<title lang="es">Destino para viajar</title>
<desc lang="es">Te invitamos a conocer los mejores destinos para viajar, donde podrás encontrar todo lo que buscas y necesitas(n)</desc>
<date>2000</date>
<category lang="es">Turismo</category>
<icon src="https://www.reportv.com.ar/buscador/img/Programas/2593324.jpg" />
</programme>
<programme start="20190222155000 -0300" stop="20190222164500 -0300" channel="AandE [ARG]">
<title lang="es">NCIS: Los Ángeles</title>
<sub-title lang="es">S.9-Ep.13 - Responsabilidades</sub-title>
<desc lang="es">Una dinámica división policial atrapa a los más peligrosos delincuentes, valiéndose astutamente de sorprendentes innovaciones tecnológicas, increíbles transformaciones físicas y arriesgadas usurpaciones de identidad. Ahora, irrumpen en la ciudad del glamour, la moda y el cine para desbaratar el reinado del crimen organizado. Callen y Sam sacan a Jennifer Kim de la protección de testigos para ayudar al equipo a encontrar un espía subterráneo con un arsenal de materiales de bombas(n)</desc>
<date>2009</date>
<category lang="es">Policial</category>
<icon src="https://www.reportv.com.ar/buscador/img/Programas/4480797.jpg" />
<country>EE.UU.</country>
<episode-num system="onscreen">S.9-Ep.13</episode-num>
</programme>
<programme start="20190222164500 -0300" stop="20190222174500 -0300" channel="AandE [ARG]">
<title lang="es">Bull</title>
<sub-title lang="es">S.2-Ep.5 - Juega con las cartas que te tocan</sub-title>
<desc lang="es">Historia inspirada en los inicios de la carrera del doctor Phil McGraw, el fundador de una de las empresas de consultoría de juicios más prolíficas de todos los tiempos. Brillante, descarado y encantador, Jason Bull es uno de los mejores maestros de marionetas ya que combina la psicología, la intuición humana y datos de alta tecnología para conocer los gustos de los miembros del jurado, los abogados, los testigos y el acusado. Él emplea a un equipo envidiable de expertos en el 'Trial Analisis Corporation' para dar forma a defensas de éxito teniendo en cuenta hasta el último detalle. Bull deberá afrontar las reglas desconocidas de una corte tribal nativa cuando su compañero de cuarto de la universidad es acusado de cometer un asesinato. Además, conoce al nuevo novio de Marissa(n)</desc>
<date>2016</date>
<category lang="es">Drama</category>
<icon src="https://www.reportv.com.ar/buscador/img/Programas/6727887.jpg" />
<country>EE.UU.</country>
<episode-num system="onscreen">S.2-Ep.5</episode-num>
</programme>
</tv>


Im Normalfall sollte das eine valide XML-Datei sein.

Kasashii
21.02.19, 09:33
Was willst Du denn genau erreichen und was soll am Ender herauskommen?

Am Ende muss ich dadurch lediglich eine Prüfung machen ob die Anzahl der gefundenen Zeilen über 5 ist.



Was spricht dagegen, die Suchstrings aus dem File direkt als Patterliste zu übergeben?
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. The empty file contains zero patterns, and therefore
matches nothing. (-f is specified by POSIX.)


selbst dabei bekam ich nicht alle Zeilen mit dem Inhalt angezeigt, hatte es so schon ausgetestet.

fork
21.02.19, 09:48
Ich würde dir gerne die Datei als Anhang hinterlegen aber irgendwas hat die Seite wohl dagegen.

Hier wird auf Dateiendung geprüft. Bitte verwende eine erlaubte Dateiendung(z. B. .txt). Dann sollte das tun.

Ansonsten bitte die CSV-Datei noch!

Wenn in der CSV-Datei so etwas drin steht: AandE [ARG], dann wird das nicht funktionieren weil [ARG] ein regulärer Ausdruck ist, der für A, R oder G steht. Da würde ein fgrep bzw. grep -F helfen. (fgrep => fixed string grep => keine Regulären Ausdrücke).

Kasashii
21.02.19, 09:56
Ok, das mit dem Format sollte man vllt besser dazu schreiben.

In der CSV Datei stehen nur die beiden Sender drin
21438

fork
21.02.19, 10:03
Na dann kannst Du ja die Kombination der beiden Lösungsvorschläge nutzen...



xmlstarlet sel -t -v "//@channel" data.xml | grep -f muster.txt -c



Ok, das mit dem Format sollte man vllt besser dazu schreiben.

Das steht da!
Erlaubte Dateierweiterungen: bmp bz doc gif gz jpe jpeg jpg pdf png psd tar txt zip

XPath

Den Audruck //@channel nennt man einen XPath-Ausdruck. Und wie der so aufgebaut werden kann, verrät Dir unter anderem ein Tutorial dazu: https://www.w3schools.com/xml/xpath_intro.asp

Im übrigen scheint die einfache grep-Variante nicht praktikabel, weil die Suchwörter an mehreren Stellen auftauchen.

Kasashii
21.02.19, 11:57
Danke @fork, das mit dem xmlstarlet funktioniert perfekt, nur läuft der grep nicht durch. Wenn ich die Wörter über read line einlese und dann ausführe findet er zumindest bei America Sports keine Ergebnisse. Gebe ich das allerdings einfach in den grep ein kommen diese natürlich. In der Variable kann ich das auch nicht quoten.

fork
21.02.19, 12:27
Bitte zeige Deine ausgeführten Befehle komplett inkl. Fehlermeldungen und Ausgaben. Bei den Eingabedateien gehe ich von dem aus, was Du bisher gezeigt hast.

Kasashii
21.02.19, 12:43
while read channelvariable; do

xmlstarlet sel -t -v "//@channel" $pasu | grep -f $pfad/testdatei1.csv -c

xmlstarlet sel -t -v "//@channel" $pasu > $pfad/ergebnis.xml

grep -c $channelvariable $pfad/ergebnis.xml

grep -c "$channelvariable" $pfad/ergebnis.xml

done < "$pfad/testdatei1.csv"


Ich habe dabei jetzt einmal den grep direkt ausgegeben und einmal das Ergebnis in einer Datei zwischengespeichert.

Bei der Ausgabe erhalte ich lediglich nur 0, da er angeblich nichts finden kann.

Ja die Eingabedateien sind die bisher bekannten.

fork
21.02.19, 13:45
Kannst Du nochmal genau beschreiben, was Du machen möchtest? Ich bin mir nicht sicher ob ich es verstanden habe.

Möchtest Du die Anzahl der Vorkommnisse für jeden einzelnen Wert aus der Datei $pfad/testdatei1.csv im channel-Attribut der XML-Datei haben oder reicht auch die Anzahl aller Werte in den channel-Attributen?

Kasashii
21.02.19, 15:00
Ich habe in der Datei testdatei1.csv mehrere 1000 Sender eingetragen. Jeder dieser Sender muss jetzt in den XML-file geprüft werden ob er öfters als 3 mal vorkommt, da sonst der Abgriff nicht erfolgreich war.

fork
21.02.19, 15:29
awk ist bei jeglicher Textverarbeitung immer ganz praktisch(Bitte exakt so eingeben und nur die Dateinamen anpassen)...



xmlstarlet sel -t -v "//@channel" data.xml | awk '

FNR==NR { muster[$1]=0;next }

{
for(m in muster)
if(match($0,m))
muster[m]++
}

END {
for(m in muster)
if(muster[m] <= 3)
print "Fehler: " m,muster[m]
}' muster.txt -

# Ausgabe mit den gegebenen Testdaten:

Fehler: America 2
Fehler: AandE 2


Eine Einführung zu awk gibt's hier:

https://riptutorial.com/de/awk/topic/937/erste-schritte-mit-awk

Etwas umfangreicher beim Rheinwerk Verlag:

http://openbook.rheinwerk-verlag.de/shell_programmierung/shell_015_000.htm