Si tengo un comando awk

pattern { ... }

y el patrón utiliza un grupo de captura, ¿cómo puedo tener acceso a la cadena por lo capturado en el bloque?

  • stackoverflow.com/questions/1555173/…
  • A veces (en casos sencillos) es posible ajustar el separador de campo (FS) y escoger lo que a uno le gusta para que coincida con un $field. Preformatting la entrada podría ayudar también.
  • No es un mejor respuesta en la pregunta duplicada.
  • Samuel Edwin Barrio: Esa es una buena respuesta! Pero también requiere gawk (ya que utiliza gensub).
InformationsquelleAutor rampion | 2010-06-02

6 Comentarios

  1. 147

    Que fue un paseo por el carril de la memoria…

    He sustituido awk por perl hace mucho tiempo.

    Al parecer, el AWK motor de expresiones regulares no capturar a sus grupos.

    usted podría considerar el uso de algo como :

    perl -n -e'/test(\d+)/&& print $1'

    la -n de la bandera de las causas de perl para recorrer cada línea como awk hace.

    • Al parecer alguien no está de acuerdo. Esta página web es del año 2005 : tek-tips.com/faqs.cfm?fid=5674 Se confirma que no se puede reutilizar grupos comparables en awk.
    • este artículo parece estar de acuerdo con usted también.
    • Como el tek-consejos artículo unidos, gawk puede volver a utilizar la captura de grupos.
    • Yo prefiero ‘perl -p-n -e…’ a más de awk para casi todos los casos de uso, ya que es más flexible, más potente y tiene una cuerdo de sintaxis en mi opinión.
    • Estoy de acuerdo, por favor, edite algo en su pregunta, así que puedo cambiar mi downvote a un upvote
    • Yo : el perl de línea es ahora muy bien formateado como un bloque de código 🙂
    • gawk != awk. Son diferentes herramientas y gawk no está disponible por defecto en la mayoría de los lugares.
    • +1 esta respuesta me salvó de dos horas. Muchas gracias!
    • ¿Por qué siempre me olvide de agarrar a sólo Perl en lugar de luchar contra estos antiguos utils que son diferentes en cada sistema … Gracias señor por recordarme.
    • Gracias por la sintaxis. && y ; hecho grandes diferencias!!
    • El OP preguntó específicamente para un awk solución, así que no creo que esta es una respuesta.
    • no se puede dar una awk solución si no hay ninguna solución. En la línea 3 me explique que AWK no admite la captura de grupos y me dio una alternativa, que el OP al parecer apreciada, porque esta respuesta fue aceptada. ¿Cómo podría responder mejor a esta pregunta?
    • Me sigue olvidando Perl por las mismas razones por las que aún usar grep y/o corte en vez de awk: voy a construir a lo largo de los comandos de forma incremental. Y a veces tengo una idea vaga de que es importante que Perl es mayor que grep/awk.
    • ¿cómo ejecutar este comando con un archivo de texto como el de la entrada?
    • Estoy de acuerdo. Esto no es awk. Un awk equivalente habría sido agradable… sobre todo desde que un perl solución no puede ser considerada como una opción en mi caso.
    • Exactamente mi punto. Para los pequeños Linux embebido dispositivos, AWK puede estar disponible, pero Perl es demasiado grande y no estará allí.
    • Yo no estoy en desacuerdo con usted, sin embargo AWK no es una opción, ya sea para el OP del problema.

  2. 295

    Con gawk, puede utilizar el match función de captura de los grupos entre paréntesis.

    gawk 'match($0, pattern, ary) {print ary[1]}' 

    ejemplo:

    echo "abcdef" | gawk 'match($0, /b(.*)e/, a) {print a[1]}' 

    salidas cd.

    Nota el uso específico de gawk que implementa la característica en cuestión.

    Para un portátil alternativa se pueden obtener resultados similares con match() y substr.

    ejemplo:

    echo "abcdef" | awk 'match($0, /b[^e]*/) {print substr($0, RSTART+1, RLENGTH-1)}'

    salidas cd.

    • Sí, la gxxx variantes tienen un montón de adicional de GNU bondad y poder.
    • Esta es la respuesta correcta, en mi opinión. Me ayudó a capturar a un grupo como en Perl o Python y almacenarlo en una variable, que es EXACTAMENTE lo que yo necesitaba.
  3. 27

    Esto es algo que necesito todo el tiempo, así que he creado una función bash para ello. Se basa en glenn jackman respuesta.

    Definición

    Agregar esto a su .bash_profile etc.

    function regex { gawk 'match($0,/'$1'/, ary) {print ary['${2:-'0'}']}'; }

    Uso

    Captura de regex para cada línea en el archivo

    $ cat filename | regex '.*'

    De captura de 1 de regex de captura de grupo para cada línea en el archivo

    $ cat filename | regex '(.*)' 1
    • ¿Cómo es diferente del uso de grep -o?
    • Podría grep -o salida capturado grupos?
    • No, no podía. Sólo cubre su caso de uso cuando usted no tiene la captura de grupos. En ese caso la cosa se pone fea con encadenado grep -o‘s.
  4. 12

    Puede utilizar GNU awk:

    $ cat hta
    RewriteCond %{HTTP_HOST} !^www\.mysite\.net$
    RewriteRule (.*) http://www.mysite.net/$1 [R=301,L]
    
    $ gawk 'match($0, /.*(http.*?)$/, m) { print m[1]; }' < hta
    http://www.mysite.net/
  5. 3

    Puede simular la captura de vainilla awk demasiado, sin extensiones. No es intuitivo, aunque:

    el paso 1. uso gensub para rodear a los partidos con algún personaje que no aparece en su cadena.
    paso 2. Uso de la división contra el personaje.
    paso 3. Todos los otros elementos en el splitted matriz de captura de grupo.

    $ echo 'ab bc ad' | awk '{ split(gensub(/a./,SUBSEP"&"SUBSEP,"g",$0),la tapa,SUBSEP); la impresión de la tapa[2]"|" cap[4] ; }' 
    ab|ad 
    
    • Estoy casi segura de que gensub es un gawk función específica. ¿Qué se obtiene a partir de su awk si el tipo de awk --version ;-?). Buena suerte a todos.
    • Estoy completamente seguro de que gensub es un gawk-ism, aunque BusyBox awk también lo tiene. Esta respuesta podría realizarse también utilizando gsub, a pesar de que: echo 'ab cb ad' | awk '{gsub(/a./,SUBSEP"&"SUBSEP);split($0,cap,SUBSEP);print cap[2]"|"cap[4]}'
    • gensub() es un gawk extensión, gawk del manual de decir claramente así. Otros awk variantes también pueden implementar, pero es que todavía no POSIX. Trate de gawk –posix ‘{gsub (…)}’, y se quejan
    • usted quiere decir que se quejan de gawk --posix '{gensub(...)}'.
    • uy, sí, gensub(), perdón por la errata
    • A pesar de que estaban equivocados acerca de POSIX awk tener la gensub función, su ejemplo aplicado a un número muy limitado de escenario: el patrón completo se agrupan, no puede coincidir con algo como todos los key=(value) cuando quiero extraer sólo el value partes.
    • Bastante gente ha comentado sobre «gensub es un gawk-ismo». ¿Por qué no modificar su respuesta, al menos?

  6. 0

    Me costó un poco con el venir para arriba con un golpe de función que ajusta Pedro Tillemans respuesta pero he aquí lo que encontré:

    función regex
    {
    perl -n -e «/$1/&& printf \»%s\n\ n», «‘$1’
    }

    He encontrado esto funcionó mejor que opsb del awk basado en bash función de la siguiente expresión regular argumento, porque yo no quiero que el «ms» para ser impreso.

    '([0-9]*)ms$'
    • Yo prefiero esta solución, ya que se puede ver las partes del grupo que delimitan la captura, mientras que también la omisión de ellos. Sin embargo, podría alguien elxplain cómo funciona esto? Yo no puedo conseguir que este perl sintaxis para trabajar correctamente en BASH, porque no la entiendo muy bien especialmente con el doble/single-comillas alrededor de $1
    • No es algo que he hecho antes o después, pero mirando hacia atrás lo que hace es concatenar dos cadenas, la primera cadena ser en comillas dobles (esta primera cadena contiene incrustado en comillas dobles escapó con barra diagonal inversa) y la segunda cadena ser en comillas simples. A continuación, el resultado de la concatenación es suministrado como argumento a perl-e. También necesitan saber que los primeros $1 (el que está dentro de las comillas dobles) es sustituido por el primer argumento de la función, mientras que el segundo $1 (el que está dentro de las comillas simples) se deja intacto. Consulte este ejemplo
    • Veo, que hace un poco más de sentido ahora. Así que cuando en el perl de comando es el regex partido/grupo de captura de definición? Veo que escribió '([0-9]*)ms$' – es que se suministra como un argumento (y la cadena de otro argumento)? Y la salida de perl -e se inserta en bash printf de comandos a continuación, para reemplazar %s, ¿es eso cierto? Gracias, estoy esperando a usar este.
    • Se pasa de una expresión regular entre comillas simples como el único argumento para la regex función bash. Ejemplo

Dejar respuesta

Please enter your comment!
Please enter your name here