Come stampare pattern regex abbinati usando awk?

Usando awk , ho bisogno di trovare una parola in un file che corrisponda a un modello regex.

Voglio solo stampare la parola corrispondente al modello.

Quindi, se in linea, ho:

 xxx yyy zzz 

E modello:

 /yyy/ 

Voglio solo ottenere:

 yyy 

EDIT: grazie a kurumi sono riuscito a scrivere qualcosa del genere:

 awk '{ for(i=1; i<=NF; i++) { tmp=match($i, /[0-9]..?.?[^A-Za-z0-9]/) if(tmp) { print $i } } }' $1 

e questo è quello che mi serviva 🙂 grazie mille!

Questo è molto semplice

 awk '/pattern/{ print $0 }' file 

chiedere a awk di cercare il pattern usando // , quindi stampare la linea, che per impostazione predefinita è chiamata record, denotata da $ 0. Almeno leggi la documentazione .

Se vuoi solo stampare la parola abbinata.

 awk '{for(i=1;i<=NF;i++){ if($i=="yyy"){print $i} } }' file 

Sembra che tu stia cercando di emulare il comportamento grep -o GNU. Questo lo farà fornendoti solo la prima corrispondenza su ogni riga:

 awk 'match($0, /regex/) { print substr($0, RSTART, RLENGTH) } ' file 

Ecco un esempio:

 % awk 'match($0, /at/) { print substr($0, RSTART, RLENGTH) } ' /usr/share/dict/words | head act act act act aft ant apt art art art 

Per il resto dei tuoi compiti, dovresti cercare in che modo ciascuno di essi match , RLENGTH fanno RSTART e RLENGTH nel manuale di awk .

Dopodiché potresti voler estendere questo per affrontare più partite sulla stessa linea. Non posso fare tutti i compiti per te 🙂

gawk può ottenere la parte corrispondente di ogni riga usando questo come azione:

 { if (match($0,/your regexp/,m)) print m[0] } 

match (string, regexp [, array]) Se array è presente, viene cancellato e quindi l’elemento zeroth dell’array viene impostato sull’intera porzione di stringa corrispondente a regexp. Se regexp contiene parentesi, gli elementi di array con numero intero sono impostati per contenere la porzione di stringa corrispondente alla sottoespressione parentesi corrispondente. http://www.gnu.org/software/gawk/manual/gawk.html#String-Functions

Se Perl è un’opzione, puoi provare questo:

 perl -lne 'print $1 if /(regex)/' file 

Per implementare la corrispondenza senza distinzione tra maiuscole e minuscole, aggiungi il modificatore i

 perl -lne 'print $1 if /(regex)/i' file 

Per stampare tutto DOPO la partita:

 perl -lne 'if ($found){print} else{if (/regex(.*)/){print $1; $found++}}' textfile 

Per stampare la partita e tutto il resto della partita:

 perl -lne 'if ($found){print} else{if (/(regex.*)/){print $1; $found++}}' textfile 

Se ti interessa solo l’ultima riga di input e pensi di trovare solo una corrispondenza (ad esempio una parte della riga di riepilogo di un comando shell), puoi provare anche questo codice molto compatto, adottato da Come stampare corrispondenze regexp usando `awk`? :

 $ echo "xxx yyy zzz" | awk '{match($0,"yyy",a)}END{print a[0]}' yyy 

O la versione più complessa con un risultato parziale:

 $ echo "xxx=a yyy=b zzz=c" | awk '{match($0,"yyy=([^ ]+)",a)}END{print a[1]}' b 

Attenzione: la funzione awk match() con tre argomenti esiste solo in gawk , non in mawk

Ecco un’altra bella soluzione che utilizza una regex di lookbehind in grep invece di awk . Questa soluzione ha requisiti inferiori per l’installazione:

 $ echo "xxx=a yyy=b zzz=c" | grep -Po '(?<=yyy=)[^ ]+' b 

L’uso di sed può anche essere elegante in questa situazione. Esempio (sostituire la linea con il gruppo corrispondente “yyy” dalla riga):

 $ cat testfile xxx yyy zzz yyy xxx zzz $ cat testfile | sed -r 's#^.*(yyy).*$#\1#g' yyy yyy 

Pagina del manuale pertinente: https://www.gnu.org/software/sed/manual/sed.html#Back_002dreferences-and-Subexpressions