regex - functions - ciclo for awk
Cómo imprimir el patrón de expresión regular combinado usando awk? (6)
Usando awk
, necesito encontrar una palabra en un archivo que coincida con un patrón de expresiones regulares.
Solo quiero imprimir la palabra que coincide con el patrón.
Entonces, si estoy en la línea, tengo:
xxx yyy zzz
Y patrón:
/yyy/
Solo quiero obtener:
yyy
EDITAR: gracias a kurumi me las arreglé para escribir algo como esto:
awk ''{
for(i=1; i<=NF; i++) {
tmp=match($i, /[0-9]..?.?[^A-Za-z0-9]/)
if(tmp) {
print $i
}
}
}'' $1
y esto es lo que necesitaba :) ¡muchas gracias!
Este es el muy básico
awk ''/pattern/{ print $0 }'' file
pregunte awk
para buscar el pattern
usando //
, luego imprima la línea, que por defecto se llama un registro, denotado por $ 0. Al menos lee la documentation .
Si solo desea imprimir la palabra coincidente.
awk ''{for(i=1;i<=NF;i++){ if($i=="yyy"){print $i} } }'' file
Parece que intentas emular el comportamiento grep -o
de GNU. Esto hará eso siempre que solo desee la primera coincidencia en cada línea:
awk ''match($0, /regex/) {
print substr($0, RSTART, RLENGTH)
}
'' file
Aquí hay un ejemplo:
% awk ''match($0, /a.t/) {
print substr($0, RSTART, RLENGTH)
}
'' /usr/share/dict/words | head
act
act
act
act
aft
ant
apt
art
art
art
Para el resto de su tarea, debe buscar lo que cada uno de los match
, subst
RSTART
y RLENGTH
hacer en el manual de awk
.
Después de eso, es posible que desee extender esto para tratar con múltiples coincidencias en la misma línea. No puedo hacer toda tu tarea por ti :-)
Si Perl es una opción, puede intentar esto:
perl -lne ''print $1 if /(regex)/'' file
Para implementar la coincidencia insensible a mayúsculas y minúsculas, agregue el modificador i
perl -lne ''print $1 if /(regex)/i'' file
Para imprimir todo DESPUÉS del partido:
perl -lne ''if ($found){print} else{if (/regex(.*)/){print $1; $found++}}'' textfile
Para imprimir el partido y todo después del partido:
perl -lne ''if ($found){print} else{if (/(regex.*)/){print $1; $found++}}'' textfile
Si solo está interesado en la última línea de entrada y espera encontrar solo una coincidencia (por ejemplo, una parte de la línea de resumen de un comando de shell), también puede probar este código muy compacto, adoptado a partir de coincidencias de impresión de expresiones regulares en AWK :
$ echo "xxx yyy zzz" | awk ''{match($0,"yyy",a)}END{print a[0]}''
yyy
O la versión más compleja con un resultado parcial:
$ echo "xxx=a yyy=b zzz=c" | awk ''{match($0,"yyy=([^ ]+)",a)}END{print a[1]}''
b
Advertencia: la función awk
match()
con tres argumentos solo existe en gawk
, no en mawk
Aquí hay otra buena solución que usa un lookgere regex en grep
en lugar de awk
. Esta solución tiene requisitos más bajos para su instalación:
$ echo "xxx=a yyy=b zzz=c" | tail -n1 | grep -Po ''(?<=yyy=)[^ ]+''
b
Usar sed también puede ser elegante en esta situación. Ejemplo (reemplace la línea con el grupo "yyy" correspondiente de la línea):
$ cat testfile
xxx yyy zzz
yyy xxx zzz
$ cat testfile | sed -r ''s#^.*(yyy).*$#/1#g''
yyy
yyy
Página de manual relevante: https://www.gnu.org/software/sed/manual/sed.html#Back_002dreferences-and-Subexpressions
gawk puede obtener la parte coincidente de cada línea usando esto como acción:
{ if (match($0,/your regexp/,m)) print m[0] }
match (cadena, regexp [, matriz]) Si la matriz está presente, se borra, y luego el elemento zeroth de la matriz se establece en la porción completa de la cadena que coincide con regexp. Si regexp contiene paréntesis, los elementos indexados enteros de la matriz están configurados para contener la porción de cadena que coincide con la subexpresión entre paréntesis correspondiente. http://www.gnu.org/software/gawk/manual/gawk.html#String-Functions