Saltar al contenido

Separador de campo predeterminado para awk

Este equipo especializado despúes de varios días de investigación y de juntar de información, encontramos la respuesta, deseamos que resulte de gran utilidad en tu plan.

Solución:

Aquí está un resumen pragmático eso se aplica a todas las principales implementaciones de Awk:

  • ÑU Awk (gawk) – el valor por defecto awk en algunos Distribuciones de Linux
  • Mawk (mawk) – el valor por defecto awk en algunos Distribuciones de Linux (por ejemplo, versiones anteriores de Ubuntu crysman informa que la versión 19.04 ahora viene con ÑU Awk, mira su comentario a continuación.)
  • BSD Awk – también conocido como BWK Awk – el valor predeterminado awk en plataformas similares a BSD, incluido OSX

En Linux, awk -W version le dirá qué implementación es la predeterminada awk es.
BSD Awk solamente entiende awk --version (que GNU Awk entiende además para awk -W version).

Versiones recientes de todos estas implementaciones siguen el estándar POSIX con respecto a campo separadores[1] (pero no registro separadores).

Glosario:

  • RS es el aporte-registro separador, que describe cómo se divide la entrada en registros:

    • los Valor predeterminado exigido por POSIX es un nueva línea, también conocido como n debajo; es decir, la entrada se rompe en líneas por defecto.
    • Sobre awklínea de comando, RS se puede especificar como -v RS=.
    • POSIX restringe RS a un literal, de un solo carácter valor, pero GNU Awk y Mawk son compatibles multicaracteres valores que pueden ser expresiones regulares extendidas (BSD Awk hace no apoyar eso).
  • FS es el aporte-campo separador, que describe cómo cada registro se divide en los campos; puede ser un expresión regular extendida.

    • Sobre awklínea de comando, FS se puede especificar como -F (o -v FS=).
    • El valor predeterminado exigido por POSIX es formalmente a espacio (0x20), pero ese espacio no es literalmente interpretado como el (único) separador, pero tiene significado especial; vea abajo.

Por defecto:

  • cualquier carrera de espaciosy / opestañas y / o nuevas líneas es tratado como un separador de campo
  • con ejecuciones iniciales y finales ignoradas.

La especificación POSIX. usa la abstracción para espacios y tabulaciones, lo que es cierto para todos locales, pero podría comprender adicional personajes en lugares específicos, no sé si existen tales lugares.

Tenga en cuenta que con el separador de registro de entrada predeterminado (RS), n, nuevas líneas típicamente no ingrese la imagen como separadores de campo, porque sin registro sí mismo contiene n en ese caso.

Nuevas líneas como separadores de campo hacer ven a jugar, sin embargo:

  • Cuando RS se establece en un valor que da como resultado registros ellos mismos conteniendo n instancias (como cuando RS está configurado en el cuerda vacía; vea abajo).
  • Generalmente, cuando el split() La función se usa para dividir una cadena en elementos de matriz sin un argumento separador de campo explícito.
    • A pesar de registros de entrada no contendrá n instancias en caso de que el RS está en efecto, el split() función cuando se invoca sin un argumento separador de campo explícito en un cadena de varias líneas de una fuente diferente (por ejemplo, una variable pasada a través del -v opción o como un pseudo-nombre de archivo) siempre golosinas n como un separador de campo.

Consideraciones importantes NO predeterminadas:

  • Asignar el vacío encadenar a RS tiene un significado especial: lee la entrada en modo párrafo, lo que significa que la entrada se divide en registros por carreras de líneas no vacías, con ejecuciones iniciales y finales de líneas vacías ignoradas.

  • Cuando usted asignar cualquier cosa otro que un literal espacio para FS, los interpretación de FScambia fundamentalmente:

    • A soltero carácter o cada carácter de un carácter especificado colocar es Reconocido individualmente como un separador de campo – no carreras de él, como con el predeterminado.
      • Por ejemplo, establecer FS para [ ] – a pesar de que efectivamente equivale a un solo espacio – hace que cada individual instancia de espacio en cada registro para ser tratado como un separador de campo.
      • Reconocer carreras, el cuantificador de expresiones regulares (símbolo de duplicación) + debe ser usado; p.ej, [t]+ reconocería carreras de pestañas como un solo separador.
    • Liderando y arrastrando los separadores NO se ignorany, en cambio, separar vacío los campos.
    • Configuración FS al cuerda vacía significa que cada personaje de un récord es su propio campo.
  • Según lo ordena POSIX, si RS está configurado en el cuerda vacía (modo párrafo), nuevas líneas (n) están además separadores de campo considerados, independientemente del valor de FS.

[1] Desafortunadamente, GNU Awk hasta al menos la versión 4.1.3 cumple con una obsoleto Estándar POSIX con respecto a los separadores de campo cuando usa la opción para hacer cumplir el cumplimiento de POSIX, -P (--posix): con esa opción en vigor y RS establecido en un no vacio valor, nuevas líneasn instancias) NO se reconocen como separadores de campo. El manual de GNU Awk detalla el comportamiento obsoleto (pero omite mencionar que no se aplica cuando RS está configurado en el vacío cuerda). El estándar POSIX cambió en 2008 (ver comentarios) a además considerar nuevas líneas separadores de campo cuando FS tiene su valor predeterminado, como siempre ha hecho GNU Awk sin-P (--posix).
Aquí hay 2 comandos que verifican el comportamiento descrito anteriormente:
* Con -P en efecto y RS establecido en el cuerda vacía, n es todavía tratado como un separador de campo:
gawk -P -F' ' -v RS='' ' printf "<%s>, <%s>n", $1, $2 ' <<< $'anb'

* Con -P en efecto y un no vacioRS, n NO se trata como un separador de campo; este es el comportamiento obsoleto:
gawk -P -F' ' -v RS='|' ' printf "<%s>, <%s>n", $1, $2 ' <<< $'anb'
Se acerca una solución, según los mantenedores de GNU Awk; esperarlo en la versión 4.2 (no se da un marco de tiempo).
(Sugerencia del sombrero para @JohnKugelman y @EdMorton por su ayuda).

La pregunta the default delimiter is only space for awk? es ambiguo, pero intentaré responder a las dos preguntas que pueda estar haciendo.

El valor predeterminado de la FS La variable (que contiene el separador de campo que le dice a awk cómo separar registros en campos a medida que los lee) es un carácter de espacio único.

Lo que utiliza awk para separar registros en campos es un "separador de campo", que es una expresión regular con alguna funcionalidad adicional que solo se aplica cuando el separador de campo es un solo carácter en blanco. Esa funcionalidad adicional es que:

  1. Los espacios en blanco iniciales y finales se ignoran durante la división de campos.
  2. Los campos están separados en cadenas de caracteres de espacios contiguos que incluyen espacios en blanco, tabulaciones y nuevas líneas.
  3. Si desea utilizar un carácter literal en blanco como separador de campo, debe especificarlo como [ ] en lugar de solo un carácter en blanco literal independiente como podría hacerlo en una expresión regular.

Además de los separadores de campo que se utilizan para dividir registros en campos a medida que se lee la entrada, se utilizan en algunos otros contextos, por ejemplo, el tercer argumento para split(), por lo que es importante que sepa qué contextos requieren una cadena o una expresión regular o un fieldsep y la página de manual especifica claramente cada uno.

Entre otras cosas, lo anterior explica esto:

$ echo ' a b c ' | awk 'printf "%d: <%s> <%s> <%s>n", NF, $1, $2, $3'
3:   
$ echo ' a b c ' | awk -F' ' 'printf "%d: <%s> <%s> <%s>n", NF, $1, $2, $3'
3:   
$ echo ' a b c ' | awk -F'[ ]' 'printf "%d: <%s> <%s> <%s>n", NF, $1, $2, $3'                              
5: <>  

así que si no entiende por qué los 2 primeros producen el mismo resultado pero el último es diferente, pregunte.

Echemos un vistazo a la página de manual de GNU awk:

FS - El separador de campo de entrada, un espacio por defecto. Ver Los campos, encima.

Al Los campos ¡sección!

A medida que se lee cada registro de entrada, gawk divide el registro en campos, utilizando el valor del FS variable como separador de campo. Si FS es un solo carácter, los campos están separados por ese carácter. Si FS es la cadena nula, entonces cada carácter individual se convierte en un campo separado. De lo contrario, FS se espera que sea una expresión regular completa. En el caso especial de que FS es un solo espacio, Los campos están separados por tramos de espacios y / o tabulaciones y / o líneas nuevas.

Reseñas y valoraciones

Tienes la posibilidad difundir este tutorial si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Respuestas a preguntas comunes sobre programacion y tecnología