[awk] relative Feldangabe ("var = wert" und "var=wert")

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
MoonKid
Beiträge: 513
Registriert: 12.03.2012 22:36:43

[awk] relative Feldangabe ("var = wert" und "var=wert")

Beitrag von MoonKid » 13.06.2015 05:13:43

Aus dieser Zeile extrahiere ich mit sed den Wert der Variable.

Code: Alles auswählen

     name = Icke
Mit diesem sed-Befehl

Code: Alles auswählen

NAME=$(awk '/.*name.*/ {print $3}' dateiname
Nun könnte die Datei aber auch so aussehen.

Code: Alles auswählen

var1 = 8, var2 = test, name = Icke
In diesem Fal wird der sed-Aufruf nicht mehr funktionieren.
Gibt es eine Möglichkeit des Feld für print relativ zum Fundort von "name" anzugeben. z.B. so

Code: Alles auswählen

NAME=$(awk '/.*name.*/ {print $+2}' dateiname

MoonKid
Beiträge: 513
Registriert: 12.03.2012 22:36:43

"var = wert" und "var=wert"

Beitrag von MoonKid » 13.06.2015 05:17:44

Ich möchte per awk/sed/dingsbums aus einer Textdatei die Werte von Variablen auslesen. Dabei ist nicht definiert, ob vor und/oder nach dem '=' ein Leerzeichen steht oder nicht.

Code: Alles auswählen

var1 = wert
var2=wert
Wie kann ich das beim Auslesen berücksichtigen?

Die erste Variante lese ich derzeit in etwa so aus

Code: Alles auswählen

awk '/.*name.*/ {print $3}'

Benutzeravatar
4A4B
Beiträge: 926
Registriert: 09.11.2011 11:19:55
Kontaktdaten:

Re: "var = wert" und "var=wert"

Beitrag von 4A4B » 13.06.2015 08:59:19

Du könntest das Gleichheitszeichen als zusätzlichen Field Separator definieren und dann das zweite Feld ausgeben

Code: Alles auswählen

awk -F [\s=] '{print $2}'

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

Re: "var = wert" und "var=wert"

Beitrag von rendegast » 13.06.2015 11:50:28

Die Sache vielleicht "normalisieren",
ein Einstieg

Code: Alles auswählen

cat ./text | egrep -o "[^,[:space:]]*[[:space:]]*=[^,]*" | sed 's@[[:space:]]*=[[:space:]]*@=@;s@^[[:space:]]*@@'
echo -------------------------------------
cat ./text | egrep -o "[^,]*=[^,]*" | sed 's@[[:space:]]*=[[:space:]]*@=@;s@^[[:space:]]*@@'
Es sollte vielleicht auf die Erstellungsart der Eingabedatei geachtet werden,
oder wird beliebiger Text geparst, um Variablenwerte zu finden?


Zusammenführung der Threads?
viewtopic.php?t=155934
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

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

Re: [awk] relative Feldangabe

Beitrag von rendegast » 13.06.2015 11:50:44

Die Sache vielleicht "normalisieren",
ein Einstieg

Code: Alles auswählen

cat ./text | egrep -o "[^,[:space:]]*[[:space:]]*=[^,]*" | sed 's@[[:space:]]*=[[:space:]]*@=@;s@^[[:space:]]*@@'
echo -------------------------------------
cat ./text | egrep -o "[^,]*=[^,]*" | sed 's@[[:space:]]*=[[:space:]]*@=@;s@^[[:space:]]*@@'
Es sollte vielleicht auf die Erstellungsart der Eingabedatei geachtet werden,
oder wird beliebiger Text geparst, um Variablenwerte zu finden?


Zusammenführung der Threads?
viewtopic.php?&t=155935
Zuletzt geändert von rendegast am 13.06.2015 12:09:12, insgesamt 4-mal geändert.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

linuxCowboy
Beiträge: 287
Registriert: 05.02.2013 19:47:41

Re: [awk] relative Feldangabe

Beitrag von linuxCowboy » 13.06.2015 11:52:18

MoonKid hat geschrieben:In diesem Fal wird der sed-Aufruf nicht mehr funktionieren. Gibt es eine Möglichkeit...
sed

Code: Alles auswählen

echo var1 = 8, var2 = test, name = Icke | sed -nr 's/.*name\s*=\s*(\S+).*/\1/p'
perl

Code: Alles auswählen

echo name = Icke | perl -nE 'say $1 if /name\s*=\s*(\S+)/'
-der_linux_cowboy --- Besser werden! ... f*** w$$

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

Re: [awk] relative Feldangabe

Beitrag von tobo » 13.06.2015 14:12:01

Vielleicht besser mit Wortgrenzen arbeiten:

Code: Alles auswählen

PIPE | sed -r 's/^.*name\s*=\s*(\w+).*/\1/'

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

Re: [awk] relative Feldangabe ("var = wert" und "var=wert")

Beitrag von Meillo » 14.06.2015 09:23:10

(Ich habe die Themen zusammen gefuehrt.)


Das Problem habe ich wie schon vorgeschlagen in zwei Schritten geloest. Zuerst normalisiere ich den Input, dann greife ich den entsprechenden Wert raus.

Normalisierungscode:

Code: Alles auswählen

/^[ \t]*#/ { next }
/^[ \t]*$/ { next }

{
        gsub(/[ \t]*=[ \t]*/, " = ")
        gsub(/,[ \t]+/, "\n")
        print
}
(Die ersten beiden Regeln entfernen Kommentar- und Leerzeilen, und sind damit optional.)

Den Wert greife ich dann so heraus:

Code: Alles auswählen

<input awk -f norm.awk | awk '$1=="foo" { print $3 }'
(``foo'' muss durch den Variablennamen ersetzt werden.)

Als Testinput habe ich Folgendes verwendet:

Code: Alles auswählen

var3 = foo
var4=bar
var1 = 8, var2 = test, name = Icke
var5=fuenf, var6= sechs,      var7 =sieben
Use ed once in a while!

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: [awk] relative Feldangabe ("var = wert" und "var=wert")

Beitrag von Phineas » 14.06.2015 10:44:05

Wenn man alles bis zum gesuchten Schlüsselwort inkl. Gleichheitszeichen (mitsamt beliebiger Anzahl von Leerzeichen) abschneidet, bleibt der gesuchte Wert in $1 übrig.
Die Funktion sub() bietet auch gleich die Bedingung (nur wenn geschnitten werden konnte, gib $1 aus):

Code: Alles auswählen

echo 'var1 = 8, var2 = test, name  =   Icke' | awk 'sub(/^.*name *=/,"") {print $1}'
Das sollte eine sehr robuste und einfach zu realisierende Sache sein.

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

Re: [awk] relative Feldangabe ("var = wert" und "var=wert")

Beitrag von Meillo » 14.06.2015 12:04:51

Phineas hat geschrieben:

Code: Alles auswählen

echo 'var1 = 8, var2 = test, name  =   Icke' | awk 'sub(/^.*name *=/,"") {print $1}'
Das sollte eine sehr robuste und einfach zu realisierende Sache sein.
Sehr robust scheint mir das aber nicht zu sein. Was ist mit ``foobar=a, bar=b''? Du brauchst zumindest noch die Beruecksichtigung von Wortgrenzen um nicht an Suffixen bei Variablennamen zu scheitern. Und du musst noch die Kommas entfernen, da bei dir die Suche nach `var2' ``test,'' ausgibt.

Einfach zu realisieren ist dein Vorschlag, aber robust ist er nicht. ;-)
Use ed once in a while!

Benutzeravatar
Phineas
Beiträge: 348
Registriert: 20.06.2012 20:26:19

Re: [awk] relative Feldangabe ("var = wert" und "var=wert")

Beitrag von Phineas » 14.06.2015 12:37:33

Das ist eine Frage der Regeln. Ich kann natürlich auch noch welche dazu erfinden. Aber sei es drum:

Code: Alles auswählen

echo 'var1 = 8, var2 = test, vorname = false name  =   Icke, noch was' | awk 'sub(/^.*\<name *=/,"") {gsub(/,/,"",$1);print $1}'

MoonKid
Beiträge: 513
Registriert: 12.03.2012 22:36:43

Re: [awk] relative Feldangabe ("var = wert" und "var=wert")

Beitrag von MoonKid » 18.06.2015 22:17:12

Interessante herangehensweise. Kann es sogar annährend nachvollziehen. ;)
Meillo hat geschrieben:Normalisierungscode:

Code: Alles auswählen

/^[ \t]*#/ { next }
/^[ \t]*$/ { next }

{
        gsub(/[ \t]*=[ \t]*/, " = ")
        gsub(/,[ \t]+/, "\n")
        print
}
Ich bekomme es gerade nicht hin, diesen Code in eine Variable zu schreiben. Möchte es nicht in eine Datei auslagern, sondern in meinem Script verwenden.
Etwa so:

Code: Alles auswählen

AWK_NORM='
/^[ \t]*#/ { next };
/^[ \t]*$/ { next };

{
        gsub(/[ \t]*=[ \t]*/, " = ");
        gsub(/,[ \t]+/, "\n");
        print
}'

awk $AWK_NORM input

newdeb
Beiträge: 134
Registriert: 03.02.2011 11:11:21
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Frankfurt

Re: [awk] relative Feldangabe ("var = wert" und "var=wert")

Beitrag von newdeb » 19.06.2015 08:39:31

Quotieren sollte helfen:

Code: Alles auswählen

awk "$AWK_NORM" input

Antworten