Digamos que tengo un archivo de texto como:
R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
Quiero usar awk
para procesar estas líneas de manera diferente, como
awk '/R1/ { print "=>" $0} /R2/ { print "*" $0} '
y también quiero imprimir el resto de las líneas tal como están (sin hacer duplicados de las líneas que ya he procesado), básicamente necesito un /ELSE/ { print $0}
al final de mi awk
línea.
¿Hay tal cosa?
awk
implementa los sospechosos habituales cuando se trata de condicionales. Es una buena idea utilizarlo enprintf
lugar deprint
para el trabajo que desea hacer en el partido.fuente
if-then-else
para esto.next
es una herramienta importante en la programación de awk.printf
aquí. Su única ventaja (a menos que esté haciendo un formato más elegante que la concatenación) es que no agrega una nueva línea, lo que no es relevante aquí.print
solo tiene que salir$0
mientras queprintf
tiene que analizar una cadena de formato.Chris Down ya mostró cómo puede obtener un else para expresiones regulares mediante el uso de una declaración explícita 'if' en un bloque. También puede obtener el mismo efecto de otras maneras, aunque su solución es probablemente mejor.
Una es escribir una tercera expresión regular que solo coincida con el texto que no coincida con los demás, en su caso, esto se vería así:
Tenga en cuenta que esto usa expresiones regulares ancladas: la ^ al comienzo de las expresiones regulares solo coincidirá al comienzo de una línea; sus patrones originales no hicieron esto, lo que ralentiza ligeramente la coincidencia ya que verificará todos los caracteres en una línea en lugar de saltando hasta la siguiente línea. El tercer caso ("else") coincidirá con una línea que comienza con algún carácter que no es 'R' ([^ R]) o que comienza con una 'R' seguida de un carácter que no es '1' o ' 2 '(R [^ 12]). Los dos significados diferentes de ^ son algo confusos, pero ese error se cometió hace mucho tiempo y no se cambiará pronto.
Para usar expresiones regulares complementarias, realmente necesitan estar ancladas, ya que de lo contrario el [^ R] coincidiría, por ejemplo, con el 1 siguiente. Para expresiones regulares muy simples como las que tiene, este enfoque puede ser útil, pero a medida que las expresiones regulares se vuelven más complejas, este enfoque será inmanejable. En su lugar, puede usar variables de estado para cada línea, así:
Esto establece que se maneje a cero para cada nueva línea, luego a 1 si coincide con cualquiera de las dos expresiones regulares, y finalmente, si aún es cero, ejecuta la impresión $ 0.
fuente
rfile
son solo 10000 líneas del conjunto de datos del interlocutor repetido.if (!handled)
¡Qué asco! Usenext
para dejar de considerar otras acciones.if (!handled)
. Las soluciones generales, flexibles y reutilizables son buenas. ¿Qué pasa si la siguiente persona que tiene esta pregunta quiere hacer más procesamiento después de la impresión? Las respuestas connext
no apoyan eso.