Hier ist ein Ausschnitt einer Zeile in der Datei:
LN=FINE FOODS & PHARMACEUTICALS NTM, MIC=XAIM, RIC=FF.MI, SG=MA1
Ich bin daran interessiert, den Wert des Tags „MIC“ zu extrahieren, d. h. meine gewünschte Ausgabe ist:
XAIM
Die ganze Zeile ist ziemlich lang:
20200403: #379 IT0005215329 {CU=EUR, GTPID=144115188076657542, II=IT0005215329, IS=18814564, LN=FINE FOODS & PHARMACEUTICALS NTM, MIC=XAIM, RIC=FF.MI, SG=MA1, SN=801670, STY=ORDINARY, TK="0.0002 to 0.1,0.0005 to 0.2,0.001 to 0.5,0.002 to 1,0.005 to 2,0.01 to 5,0.02 to 10,0.05 to 20,0.1 to 50,0.2 to 100,0.5 to 200,1 to 500,2 to 1000,5 to 2000,10 to 5000,20 to 10000,50 to 20000,100 to 50000,200", TS=FF, TY=S, UQ=1}
Die Position des Tags „MIC“ in der Zeile ist nicht immer gleich.
Ich habe mir ziemlich viele Tutorials durchgelesen und es scheint, dass alle Lösungen darin bestehen, benutzerdefinierte Feldtrennzeichen zu erstellen und dann anhand der Position des Musters in der Zeile ein gewünschtes Muster zu extrahieren.
Ich habe beispielsweise versucht, dem Beispiel ausdieser Thread, und zwar habe ich diesen Code verwendet, um den Wert aus dem Tag „MIC“ zu extrahieren:
awk 'BEGIN {FS="MIC=|,"} {print $2}' input.txt
Ich habe die folgende Ausgabe erhalten:
GTPID=144115188076657542
Wenn Sie das gesamte Zeilenbeispiel überprüfen, das ich oben bereitgestellt habe, ist die Ausgabe der Wert des zweiten Tags „GTPID“, das das Symbol „=“ hat. Zuerst dachte ich, das {FS="MIC=|,"}
bedeutet „erstelle zwei benutzerdefinierte Feldtrennzeichen, das erste ist MIC=
und das zweite ist“ ,
, und aus irgendeinem Grund erwartete ich, dass {print $2}
alles ausgedruckt wird, was zwischen diesen beiden Feldtrennzeichen steht.
Aber offensichtlich druckt der obige Code den Wert des Musters, das das Symbol "=" enthält, das zufällig an zweiter Stelle in der Zeile steht.
Wie extrahiere ich einen Wert, der zwischen MIC=
und ,
dann liegt?
Antwort1
Wenn Ihre Daten Name=Wert-Paare enthalten, sollten Sie am besten zuerst ein Array erstellen, das diese Zuordnung erfasst ( f[]
siehe unten). Anschließend können Sie einfach über den Namen auf die gewünschten Felder zugreifen, z. B.:
$ awk -F'[=,] *' '{for (i=1;i<NF;i+=2) f[$i]=$(i+1); print f["MIC"]}' file
XAIM
Sehen Sie, wie einfach es ist, dies an Testwerte anzupassen, andere Felder in beliebiger Reihenfolge auszudrucken usw.:
awk -F'[=,] *' '
{ for (i=1;i<NF;i+=2) f[$i]=$(i+1) }
(f["MIC"] == "XAIM") && (f["LN"] ~ /FOOD/){ print f["SG"], f["RIC"] }
' file
MA1 FF.MI
Antwort2
$ sed -n 's/.* MIC=\([^,}]*\).*/\1/p' file
XAIM
Dies sed
wird zum Abgleichen der Zeichenfolge MIC=SOMETHING,
oder verwendet MIC=SOMETHING}
und ersetzt die gesamte Zeile durch die SOMETHING
Zeichenfolge. Alle anderen Daten werden verworfen.
$ tr ',' '\n' <file | awk -F '=' '$1 == " MIC" { print $2 }'
XAIM
Dabei werden zunächst alle Kommas durch Zeilenumbrüche ersetzt und dann awk
mit einem =
Zeichen als Feldtrennzeichen ausgeführt. Wenn das erste Feld gleich ist MIC
, wird das zweite Feld gedruckt.
$ awk -F ',' '{ for (i = 1; i <= NF; ++i) if (sub(" MIC=","",$i)) print $i }' file
XAIM
Dabei werden die Eingaben nur awk
als durch Kommas getrennte Felder verwendet und behandelt. Es werden alle Felder durchlaufen, und wenn ein Feld mit der Zeichenfolge beginnt MIC=
, wird diese Zeichenfolge aus dem Feld entfernt und der Rest gedruckt.
Wenn die Datei im JSON-Format gewesen wäre (ich denke, Sie hätten die Daten möglicherweise transformiertausJSON irgendwann, da die meisten REST-APIs DATEN im JSON-Format zurückgeben und diese Daten mit den Finanzmärkten in Zusammenhang zu stehen scheinen):
{
"CU": "EUR",
"GTPID": 144115188076657540,
"II": "IT0005215329",
"IS": 18814564,
"LN": "FINE FOODS & PHARMACEUTICALS NTM",
"MIC": "XAIM",
"RIC": "FF.MI",
"SG": "MA1",
"SN": 801670,
"STY": "ORDINARY",
"TK": "0.0002 to 0.1,0.0005 to 0.2,0.001 to 0.5,0.002 to 1,0.005 to 2,0.01 to 5,0.02 to 10,0.05 to 20,0.1 to 50,0.2 to 100,0.5 to 200,1 to 500,2 to 1000,5 to 2000,10 to 5000,20 to 10000,50 to 20000,100 to 50000,200",
"TS": "FF",
"TY": "S",
"UQ": 1
}
dann jq
wäre es am einfachsten gewesen:
$ jq -r '.MIC' file1
XAIM
Antwort3
Mit grep
und cut
. Verwenden Sie , grep -o
um o
nur die übereinstimmenden Daten zu übernehmen, suchen Sie nach dem angeforderten Feld und Wert. Geben Sie das an weiter cut
, verwenden Sie es =
als Feldtrennzeichen, und übernehmen Sie das zweite Feld:
$ grep -o 'MIC=[^,]*' input | cut -d= -f2
XAIM
Mit sed
. Suchen Sie nach dem gewünschten Feld/Wert-Paar und extrahieren Sie mit ()
und das passende Untermuster:\1
$ sed -nE 's/^.*MIC=([^,]+).*$/\1/;p' input
XAIM
# or, alternatively,
$ sed -n 's/^.*MIC=\([^,]*\).*$/\1/;p' input
XAIM
Mit awk
. Setzen Sie den Feldtrenner und den Datensatztrenner auf =
bzw. ,
. Drucken Sie für den Datensatz mit dem übereinstimmenden Muster das zweite Feld (also den Wert):
$ awk 'BEGIN { FS="="; RS=","; } $1 ~ /MIC/ { print $2 }' input
XAIM
Antwort4
Befehl
awk -F "," '{for(i=1;i<=NF;i++){if($i ~ /MIC/){gsub(/.*=/,"",$i);print $i}}}'
Dateiname
Ausgabe
XAIM