Una pregunta sobre awk


9

Ok, como esta es una pregunta compleja, la explicaré claramente. Obtuve un contenido de archivo que se muestra a continuación:

$ Cat File1 
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}

La salida que quiero

-Cool MNB +  POP ;
-Cool MNB  + POP ;
-Cool MNB  + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD +POP ;

En primer lugar, trato de sacar la última columna del File1e imprimirla por sed 's/[{}//g' File1 > File3

Después de eso copio todo el contenido de File1un nuevoFile4

cp File1 File4

Después de eso, reemplazo los datos dentro del File4con los File3datos (significa los datos sin paréntesis una " File1última columna esa")

awk 'FNR==NR{a[NR]=$1;next}{$5=a[FNR]}1' File3 File4 >>File5 

La salida debería ser así

ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP TBMKF
ABC Cool Lol POP YUKER
ABC Cool Lol POP EFEFVD

Finalmente lo intento

awk -F " '{print - $2,$5 +,$4 ";"}‘ File5

Pero el resultado no salió como se muestra como quiero, solo se muestran todos los datos similares de MNB, otros no se presentaron (Presente los datos de la última columna),


¿Estás usando gnu awk?
123

No estoy seguro de lo que quieres decir. Pero solo soy un nuevo principiante para tocar awk. Esta es la tarea que necesito hacer, hago mi mejor esfuerzo para avanzar lentamente un paso a un paso para hacerlo basado en mi comprensión de awk.
heng960407

1
tipo awk --version, ¿cuál es el resultado?
123

2
Cambie su título a algo más específico para su problema. Esto facilitará que otras personas que tengan preguntas similares en el futuro puedan encontrarlo. Por el momento "Una pregunta sobre awk" es muy general.
Tom Fenech

Respuestas:


16

No sé por qué estás copiando cosas de izquierda a derecha. Lo simple es

awk '{print "-" $2, substr($5,2,length($5)-2), "+", $4, ";"}' File1

Puse el -principio y el ;final.

En el medio imprimimos

  • $2 porque lo queremos como es.
  • una subcadena de $5, que es la cadena sin el primer y el último carácter. Saltamos el primer carácter comenzando en la posición 2 (awk siempre ha sido extraño al respecto) y omitimos el último carácter seleccionando solo una subcadena que es dos caracteres más corta que la original$5
  • el +porque lo queremos
  • y entonces $4

Sin embargo, no estoy seguro de si todas estas funciones de cadena son específicas de GNU awk.


substr(string, 2)devuelve la subcadena a partir del segundo carácter, como cut -c2-, tail -n +2, sed '2,$'... ¿Qué tiene de extraño en ello?
Stéphane Chazelas

3
Ese comando es estándar e incluso funcionaría con el original awkde los años 70.
Stéphane Chazelas

@ StéphaneChazelas: Ah, te he estado esperando :-) Por lo general, comenzamos a contar en 0, lo que significa que el índice 2 es la tercera posición, pero aquí la segunda posición está en el índice 2. Gracias por aclarar la pregunta GNU restante.
Bananguin

@Bananguin, en Unix shell y utilidades como se muestra en los pocos ejemplos anteriores, comenzamos en 1, no en 0. Las excepciones más notables son las matrices de ksh y $ {var: offset} (ambos copiados por bash). Todas las demás matrices de shell comienzan en 1. Vea también ¿Hay alguna razón por la cual el primer elemento de una matriz Zsh está indexado por 1 en lugar de 0?
Stéphane Chazelas

7

Con sed

sed '
    s/\S\+\s/-/
    s/\(\S\+\s\)\{2\}{\(\S\+\)}/\2 + \1;/
    ' File1

Y awk variación

awk -F"[[:blank:]{}]+" '{print "-" $2, $5, "+", $4}' ORS=" ;\n" File1

6

Trabajo TXR fácil :

$ txr -c '@(repeat)
@a @b @c @d {@e}
@(do (put-line `-@b @e + @d ;`))
@(end)' -
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}
[Ctrl-D][Enter]
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD + POP ;

Usando la macro TXR Lisp awk para transcribir la solución Awk:

 txr -e '(awk (t (prn `-@[f 1] @{[f 4] [1..-1]} + @[f 3] ;`)))'

Los campos están en la flista, y la indexación está basada en cero.


1
¡+1 para el look lisp y más cruel! Ese lenguaje DEBE competir en pcg (código de programación de golf)
Archemar

@Archemar TXR no compite muy bien en el golf porque hay lenguajes especializados diseñados para eso que hacen cosas como asignar funciones a caracteres individuales, que luego se pueden unir para lograr la composición.
Kaz


1
@Kaz ¿Hay algún tutorial de TXR en alguna parte? La página del manual parece bastante grande. ¿Cómo funciona en comparación con awk?
bli

1
@bli GNU Awk es algo así como al menos 30 veces más rápido en el campo básico que se divide en un archivo grande que la macro TXR awk, que es más de 220 líneas de código interpretado , incluido el bucle general para procesar fuentes de entrada en registros y campos.
Kaz

3

Usar awk es más fácil cuando los $1,$2,...campos ya contienen las cadenas exactas con las que desea trabajar. El separador de campo, si contiene más de un carácter, se interpreta como una expresión regular. No necesitamos realizar ninguna operación de búsqueda y reemplazo o subcadena para deshacernos de las {llaves ". Solo los contamos como parte del delimitador.

awk -F'[ {}]+' '{printf("-%s %s + %s ;\n", $2, $5, $4)}'

Usar en printflugar de printtambién hace que sea un poco más fácil ver cómo se formateará la cadena, pero si desea tenerla en print "-"$2,$5" + "$4";"lugar de printf("-%s %s + %s ;\n", $2, $5, $4), esa es una opción.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.