2017-07-11 10 views
2

Ich muss alle K [A-Z] {4} und US [C, W] [0-9] {8} Werte aus jeder Zeile in einer Textdatei extrahieren.Mehrere übereinstimmende Muster aus der Textdatei extrahieren

Ich verwende den folgenden Code, um dies zu erreichen, aber ich muss diese Werte basierend auf der Bedingung extrahieren, wenn ONLY beide in einer gegebenen Zeile vorhanden sind (dh die letzten drei Zeilen in den folgenden Daten).

Versuchte Code:

#Filters out any values matching K[A-Z]{4} 
grep -Po '"\K[A-Z]{4}\b' usc.matched > out.1 

#Filters out any values matching US[C,W][0-9]{8} 
grep -Po '\bUS\w*' usc.matched > out.2 

#Pastes two datasets together, separated by a comma 
paste -d',' out.1 out.2 > stations.filtered 

#Removes any lines that do not lead with "K" 
sed -i '/^[^K]/d' stations.filtered 

JSON Daten:

{"sids": ["94737 1", "RUT 3", "KRUT 5"], "name": "RUTLAND STATE AP"}, 
{"sids": ["54740 1", "VSF 3", "KVSF 5", "USW00054740 6"], "name": "SPRINGFIELD HARTNESS AP"}, 
{"sids": ["94601 1", "RKD 3", "KRKD 5"], "name": "ROCKLAND KNOX CO RGNL AP"}, 
{"sids": ["20B 3"], "name": "ROCKLAND STN"}, 
{"sids": ["177250 2", "USC00177250 6"], "name": "ROCKLAND"}, 
{"sids": ["177255 2", "USC00177255 6", "RCKM1 7"], "name": "ROCKLAND"}, 
{"sids": ["177260 2"], "name": "ROCKLAND MOORING LBS"}, 
{"sids": [], "name": "ROCKLAND"}, 
{"sids": ["14612 1"], "name": "ROCKLAND"}, 
{"sids": ["274380 2", "USC00274380 6"], "name": "KEARSARGE"}, 
{"sids": ["192770 2", "USC00192770 6"], "name": "FISKDALE"}, 
{"sids": ["US1CTNL0005 6", "CTNL0005 10"], "name": "OAKDALE 2.6 WNW"}, 
{"sids": ["063989 2", "USC00063989 6"], "name": "LAKE KONOMOC"}, 
{"sids": ["14740 1", "14721 1", "063456 2", "069704 2", "BDL 3", "72508 4", "KBDL 5", "USW00014740 6", "BDL 7"], "name": "HARTFORD-BRADLEY INTL AP"}, 
{"sids": ["94702 1", "060806 2", "BDR 3", "72504 4", "KBDR 5", "USW00094702 6", "BDR 7"], "name": "IGOR I SIKORSKY MEMORI AP"}, 
{"sids": ["54734 1", "DXR 3", "KDXR 5", "USW00054734 6"], "name": "DANBURY MUNI AP"}, 

Stromausgang:

KRUT, 
KVSF,USW00054740 
KRKD 

USC00177250 
USC00177255 


USC00274380 
USC00192770 
US1CTNL0005 
USC00063989 
KBDL,USW00014740 
KBDR,USW00094702 
KDXR,USW00054734 

Erwartete Ausgabe:

KVSF,USW00054740 
KBDL,USW00014740 
KBDR,USW00094702 
KDXR,USW00054734 
+0

Ja, ich habe 'jq' installiert. Ich habe auch Current Output und Expected Output angefügt, um weiter zu definieren, was ich zu tun versuche – arnpry

Antwort

2

Sie verwenden können:

awk -F '[][" \t{},:]+' '{ 
a=b="" 
for(i=2; i<=NF; i++) 
    if ($i ~ /^K[A-Z]{3}$/) 
     a=$i 
    else if ($i ~ /^US[CW][0-9]+/) 
     b=$i 
    if (a != "" && b != "") 
     print a, b 
}' OFS=, file 

KVSF,USW00054740 
KBDL,USW00014740 
KBDR,USW00094702 
KDXR,USW00054734 
1

In awk. Stimmen Sie die regexen nach Ihren Wünschen:

$ awk -v OFS=, ' 
/K[A-Z]{3}/&& /US[C,W][0-9]{8}/ { 
    b="" 
    while(match($0,/K[A-Z]{3} |US[C,W][0-9]{8}/)) { 
     b=b (b==""?"":OFS) substr($0, RSTART, RLENGTH) 
     $0=substr($0,RSTART+RLENGTH) 
    } 
print b}' file 
KVSF ,USW00054740 
KBDL ,USW00014740 
KBDR ,USW00094702 
KDXR ,USW00054734 
2

wenn perl in Ordnung ist (übernimmt K String US String in derselben Zeile vorangeht)

$ perl -lne 'print "$1,$2" if /"(K[A-Z]{3})\b.*"(US[CW]\d{8}\b)/' usc.matched 
KVSF,USW00054740 
KBDL,USW00014740 
KBDR,USW00094702 
KDXR,USW00054734 
  • if /"(K[A-Z]{3})\b.*"(US[CW]\d{8}\b)/ nur wenn diese Bedingung entspricht
    • print "$1,$2" druckt die beiden erfassten Gruppen
    • "(K[A-Z]{3})\b Matches K von drei Großbuchstaben gefolgt nur von " und endend mit Wortgrenze
    • "(US[CW]\d{8}\b Streichhölzer US gefolgt von C oder W und acht Ziffern vorangestellt, wenn nur von " voraus, wenn und endet mit Wortgrenze
  • Weitere Informationen zu -lne Optionen http://perldoc.perl.org/perlrun.html#Command-Switches
Verwandte Themen