2016-07-13 21 views
0

Ich versuche, das genaue Feld des nächsten Datensatzes nach einer Übereinstimmung zu erhalten, zum Beispiel, wenn "string1" in $ 2 übereinstimmt, dann muss ich den Wert erhalten von $ 2 des nächsten Datensatzes. Ich habe etwa 100 solcher Strings, die genau einmal in einer Eingabedatei vorkommen. aber die gleiche Suchzeichenfolge kann in einer anderen Eingabedatei vorhanden sein (ich habe mehr als 1000 solcher Eingabedateien).das gleiche Feld des nächsten Datensatzes nach einem Spiel in awk

Abtastwerteingang: Komma getrennt

10.217.250.162,NTTN_EMS,Radio/AMR Configuration Slot02, 
RX RF Frequency Slot02,Channel Spacing Slot02,AMR Range (QPSK) Slot02,AMR Range (16QAM) Slot02 
37740.500 [MHz],7 [MHz],Enable,Enable 
10.217.250.162,NTTN_EMS,Radio/AMR Configuration Slot03, 
RX RF Frequency (Slot03),Channel Spacing (Slot03),AMR Range (QPSK) {(Slot03)|(SW GRP2)},AMR Range (16QAM) {(Slot03)|(SW GRP2)} 
37712.500 [MHz],7 [MHz],Enable,Enable 
10.217.250.162,NTTN_EMS,Radio/AMR Configuration Slot04, 
RX RF Frequency Slot04,Channel Spacing Slot04,AMR Range (QPSK) Slot04,AMR Range (16QAM) Slot04 
,,, 
10.217.250.162,NTTN_EMS,Radio/AMR Configuration Slot05, 
RX RF Frequency (Slot05),Channel Spacing (Slot05),AMR Range (QPSK) {(Slot05)|(SW GRP3)},AMR Range (16QAM) {(Slot05)|(SW GRP3)} 

string1, string2 .... sind Suchmuster enthält alphanumerische mit ({| zwischen Wertfelder können leer sein Anzahl der Felder nicht festgelegt ist... die Lage von string1 ist nicht festgelegt, in anderer Position auftreten kann aber nur einmal in einer Datei auftritt

, was ich bisher versucht:..

BEGIN { 
FS=OFS="," 
} 
{for (i=1;i<=NF;i++){ 
if ($i == "string1"){ 
    getline val; 
    split(val,a,","); 
    am1=a[i]} 
if ($i == "string2"){ 
    getline val; 
    split(val,a,","); 
    am2=a[i]} 
} 
} 
END {print am1,am2} 

ich weiß, dass dies nicht für die angegebene Eingabe funktioniert, da die i für aufeinanderfolgende value1 und value2 geändert wird. Sollte ich für jede einzelne Suchzeichenfolge eine andere for-Schleife verwenden? oder schlagen Sie bitte eine Lösung vor.

Such

string1="AMR Range (QPSK) Slot02",string2="AMR Range (QPSK) {(Slot03)|(SW GRP2)}",string3="AMR Range (QPSK) Slot04",string4="AMR Range (16QAM) Slot02" 

gewünschte Ausgabe:

10.217.250.162,NTTN_EMS,Enable,Enable,,Enable 
+0

Wo ist deine andere Eingabedatei, wie es aussieht und was heißt das? –

+0

Bearbeiten Sie Ihre Frage, um eine [mcve] mit prägnanten, testbaren Beispiel-Eingabe (beide Eingabedateien und ersetzen Sie alle 'blah' ',' String 'und 'Wert mit sinnvollen repräsentativen Werte) und die erwartete Ausgabe gegeben diese Eingabe. Wenn Sie jemals in Erwägung ziehen, 'getline' zu ​​verwenden, lesen Sie zuerst alle Implikationen und Vorbehalte vollständig und verstehen Sie unter http://awk.freeshell.org/AllAboutGetline. –

+0

@MarkSetchell andere Eingabedateien haben dasselbe Format, nur die Suchzeichenfolgenpositionen sind anders. – foxx

Antwort

1

Ich verstehe Ihr Ausgabeformat nicht, aber vielleicht wird dies dazu beitragen. Dies schafft die Zuordnung von Suchbegriffen auf Werte in der entsprechenden nächsten Zeile

geändert Ihre letzte Eingabezeile

$ cat file 
blah,blah,blah,string1,string2,string3,blah 
blah,blah,blah,value1,value2,value3,blah 
string4,blah,string5,string6,blah 
value4,x,value5,value6,x 

und erstellen Sie eine separate Nachschlagdatei

$ cat lookup 
string1 
string2 
string3 
string4 
string5 
string6 

und schließlich das Skript

$ awk -F, 'NR==FNR{m[$0];next} 
      FNR==1{p=$0;next} 
        {n=split(p,a); 
        for(i=1;i<=n;i++) if(a[i] in m) print a[i],$i; 
        p=$0}' lookup file 

generiert Ausgabe

string1 value1 
string2 value2 
string3 value3 
string4 value4 
string5 value5 
string6 value6 

Sie können das gleiche Skript mit mehreren Daten laufen Dateien als auch

$ awk ... lookup file1 file2 file3 ... 

und vielleicht Dateinamen im Anzeigendruck zu erkennen, welche Datei die Quelle der Spiele war.

0

Ich verstehe nicht, wie Sie die gebuchte erwartete Ausgabe des gebuchten Abtastwerteingang erhalten, aber diese Eingabe gegeben:

$ cat strings 
AMR Range (QPSK) Slot02 
AMR Range (QPSK) {(Slot03)|(SW GRP2)} 
AMR Range (QPSK) Slot04 
AMR Range (16QAM) Slot02 

$ cat file 
10.217.250.162,NTTN_EMS,Radio/AMR Configuration Slot02, 
RX RF Frequency Slot02,Channel Spacing Slot02,AMR Range (QPSK) Slot02,AMR Range (16QAM) Slot02 
37740.500 [MHz],7 [MHz],Enable,Enable 
10.217.250.162,NTTN_EMS,Radio/AMR Configuration Slot03, 
RX RF Frequency (Slot03),Channel Spacing (Slot03),AMR Range (QPSK) {(Slot03)|(SW GRP2)},AMR Range (16QAM) {(Slot03)|(SW GRP2)} 
37712.500 [MHz],7 [MHz],Enable,Enable 
10.217.250.162,NTTN_EMS,Radio/AMR Configuration Slot04, 
RX RF Frequency Slot04,Channel Spacing Slot04,AMR Range (QPSK) Slot04,AMR Range (16QAM) Slot04 
,,, 
10.217.250.162,NTTN_EMS,Radio/AMR Configuration Slot05, 
RX RF Frequency (Slot05),Channel Spacing (Slot05),AMR Range (QPSK) {(Slot05)|(SW GRP3)},AMR Range (16QAM) {(Slot05)|(SW GRP3)} 

Ich denke, die folgende tut, was Sie im Text beschreiben:

$ cat tst.awk 
BEGIN { FS=OFS="," } 
NR==FNR { strings[$0]; next } 
FNR==1 { out = $1 OFS $2 } 
{ 
    if (pos) { 
     out = out OFS $pos 
     pos = 0 
    } 
    for (i=1; i<=NF; i++) { 
     if ($i in strings) { 
      pos = i 
     } 
    } 
} 
ENDFILE { 
    if (pos) { 
     out = out OFS $pos 
     pos = 0 
    } 
    print out 
} 

$ awk -f tst.awk strings file 
10.217.250.162,NTTN_EMS,Enable,Enable, 

Die oben verwendet GNU awk für ENDFILE statt END so können Sie tun:

awk -f tst.awk strings file1 file2 .... 

oder ähnlich, um mehrere Dateien gleichzeitig zu bearbeiten.

Wenn die Saiten haben in Ihrem awk Skript hartcodiert werden, dann ist es nur ein zwicken:

$ cat tst.awk 
BEGIN { 
    FS=OFS="," 
    split("AMR Range (QPSK) Slot02\n\ 
AMR Range (QPSK) {(Slot03)|(SW GRP2)}\n\ 
AMR Range (QPSK) Slot04\n\ 
AMR Range (16QAM) Slot02", tmp, /\n/) 
    for (i in tmp) { 
     strings[tmp[i]] 
    } 
} 
FNR==1 { out = $1 OFS $2 } 
{ 
    if (pos) { 
     out = out OFS $pos 
     pos = 0 
    } 
    for (i=1; i<=NF; i++) { 
     if ($i in strings) { 
      pos = i 
     } 
    } 
} 
ENDFILE { 
    if (pos) { 
     out = out OFS $pos 
     pos = 0 
    } 
    print out 
} 

$ awk -f tst.awk file 
10.217.250.162,NTTN_EMS,Enable,Enable, 
+0

zwei zu löschende Probleme 1. Suchzeichenfolgen werden nicht in einer anderen Datei gespeichert und können nicht als Eingabe bereitgestellt werden. 2. Die Position der Suchstrings variiert von Datei zu Datei und kann daher nicht vorher bekannt sein. das bedeutet, dass die Position der Übereinstimmung aus der Datendatei selbst bekannt sein muss. – foxx

+0

Wenn Sie uns mitteilen, wo die Suchzeichenfolgen NICHT gespeichert sind, ist es nützlich, aber uns mitzuteilen, wo sie gespeichert werden, wäre wesentlich nützlicher. Einzelne Shell-Variablen? Ein Shell-Array? In awk hart codiert? Etwas anderes? Außerdem nimmt das Skript keine Annahmen über die Position der Suchzeichenfolgen vor - es findet sie nur und zeichnet die Position auf, in der sie gefunden wurden, um sie in der nachfolgenden Zeile zu verwenden. –

+0

Ich habe meine Antwort so bearbeitet, dass sie eine Version enthält, in der die Zeichenfolgen im Skript fest codiert sind, falls Sie das suchen. –