awk

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
awk [2023/04/12 01:18] peronawk [2024/03/10 18:06] (actual) peron
Línea 3: Línea 3:
 **awk** es un lenguaje de análisis y procesado orientado a patrones de texto. Está diseñado para hacer sencilla las tareas de recopilación común de información y manipulación de texto. **awk** es un lenguaje de análisis y procesado orientado a patrones de texto. Está diseñado para hacer sencilla las tareas de recopilación común de información y manipulación de texto.
  
-La operación básica de awk es analizar un conjunto de líneas de entrada en ordenbuscando por coincidencias que se han especificadoPara cada patrónpuede especificarse una acción; esta acción será llevada a cabo en cada línea que muestre coincidencias.+En la práctica, el uso de awk suele caer en dos amplias categorías. Una es la que podría considerarse **generación de informes**: esto implica el procesado de una entrada para extraer conteossumas, subtotales, etcéteraEsto también incluye la escritura de programas de validación de datos trivialescomo la verificación de campos que contengan contiene únicamente información numérica o analizar si ciertos delimitadores están adecuadamente balanceados.
  
-En la práctica, el uso de awk suele caer en dos amplias categorías. Una es la que podría llamarse "generación de informes": procesado de una entrada para extraer conteos, sumas, subtotales, etcéteraEsto también incluye la escritura de programas de validación de datos trivialescomo verificar que un campo contiene únicamente información numérica o que ciertos delimitadores están adecuadamente balanceados.+Una segunda categoría es su uso como **transformador de datos**, convirtiendo datos de la forma producida por un programa en la esperada por otro distintoLos ejemplos más simples consisten en simplemente seleccionar camposy tal vez reorganizarlos.
  
-Una segunda área de uso es como transformador de datosconviertiendo datos de la forma producida por un programa en la esperada por otro distinto. Los ejemplos más simples consisten en simplemente seleccionar camposy tal vez reorganizarlos.+>awk resulta invaluable para el el procesado textual y numérico combinado. Fue creado por AhoWeinberger y Kerningham en los [[Laboratorios Bell]]de allí su nombre.
  
->awk resulta invaluable para el el procesado textual y numérico combinado+====Uso básico====
  
-=====Design=====+La operación básica de awk es analizar un conjunto de líneas de **entrada** en orden buscando por //coincidencias// que se han especificado. Para cada patrón, puede especificarse una acción; esta acción será llevada a cabo en cada línea que muestre coincidencias, y se le dará **salida** (mostrándolo en la terminal o redirigiéndola).
  
-El sistema [[Unix]] ya provee varios programas que operan pasando entrada a travésa de una seleccion de mecanismos. Grep, el primero y más simple, simplemente imprime todas las líneas coincidentes con un único patrón simple. Egrep rpvee patrones más generales, por ejemplo, expresiones regulares en su generalidad; fgrep busca un conjunto de palabras clave con un algoritmo particularmente velozsed provee la mayoría de las facilidades de edición del editor ed, y las aplica a un flujo de caracteres de entrada. Pero ninguno de estos programas provee capacidades numéricas, relaciones lógicas o variables.+El comando  
 +<code awk>awk programa [ficheros]</code> 
 +ejecuta los comandos de awk de la cadena ''programa'' sobre el conjunto de ''ficheros'' especificados, o bien utilizará la entrada estándar si no se hubiesen espeficado fichero alguno para analizarLa declaración también puede volcarse a un ''fichero_salida'' con el prefijo ''-f'':
  
-Lex provee reconocimiento a expresiones regulares generales, y al servir como generador de programas en C - es escencialmente de final abierto en cuanto a sus posibilidades. El uso de lex, sin embargo, requiere un conocimiento de programación en lenguaje C, y un programa de lex debe compilarse y cargarse antes de usarlo, lo cual desalienta su uso para aplicaciones de un solo uso.+<code awk>awk -f fichero_salida [ficheros]</code>
  
-awk es un intetno de cubrir este nicho de posibilidades., Provee capacidades de expresiones regulares generales, y un bucle de entrada/salida implíficto. Pero también provee procesado numérico conveniente, variables, una selección más general, control de flujo en las acciones. No requiere compilación ni conocimiento de C. +====Estructura de Programa de awk====
- +
-Finalmente, awk provee una forma conveniente de acceder a campos dentro de las líneas; es único en este aspecto. +
- +
-awk también intenta integrar cadenas y números al completo, tratando todas las cantidades tanto como cadenas y números, decidiendo qué representación es apropiada tan tarde como sea posible (el reconocimiento de números se hace en idioma inglés). En la mayoría de los casos, el usuario puede simplemente ignorar las diferencias. +
- +
-La mayoría del esfuerzo de desarrollar awk se invirtió en decidir qué es lo que debía o no debía hacer (por ejemplo, no hace sustitución de cadenas), y cuál debía ser la sintaxis (no existen operadores explíficots para la concatenación) en lugar de escribir o depurar el código. +
- +
-Se intentó hacer la sintaxis poderosa pero simple de usar y bien adaptada a analizar ficheros de texto. Por ejemplo, la ausencia de declaraciones e inicializaciones implícitas, mientras probablemente sea una mala idea como lenguaje de programación de uso general, es deseable en un lenguaje que está pensado para ser utilizado por pequeños programas que puedan ser incluso compuestos desde la línea de comandos. +
- +
-====Estructura de Programa====+
  
 Un //programa de awk// es una secuencia de declaraciones que guardan la siguiente sintaxis: Un //programa de awk// es una secuencia de declaraciones que guardan la siguiente sintaxis:
Línea 35: Línea 27:
 A su turno, cada línea de //entrada// resulta analizada por awk contra cada //[[#patrones|patrón]]//. En cada uno de los patrones en los que encuentre coincidencia, awk ejecutará la //[[#accion|acción]]// solicitada. Una vez que awk ha finalizado de evaluar todos los patrones solicitados en la línea, cargará la siguiente línea, y comenzará nuevamente el análisis de la misma. A su turno, cada línea de //entrada// resulta analizada por awk contra cada //[[#patrones|patrón]]//. En cada uno de los patrones en los que encuentre coincidencia, awk ejecutará la //[[#accion|acción]]// solicitada. Una vez que awk ha finalizado de evaluar todos los patrones solicitados en la línea, cargará la siguiente línea, y comenzará nuevamente el análisis de la misma.
  
-En cada declaración del programa pueden omitirse tanto el patrón como acciónpero no pueden omitirse ambas. Si un patrón carece de acción, la línea coincidente simplemente se presenta como //salida// (por lo tanto una linea con muchos patrones coincidentes puede resultar impresa varias veces). Si una acción carece de patrones, entonces dicha acción se se realizará para cada línea de entrada+Como en las declaraciones del programa awk tanto los patrones como acciones son opcionalescomo forma de distinguir unos de otras se encierra la acción entre llaves ''{}'' para distinguirla.
  
-Naturalmente, las líneas cuyos patrones no tienen coincidenciaresultan ignoradas ("filtradas").+En cada declaración del programa pueden omitirse tanto el patrón como acciónpero no pueden omitirse ambas: 
 +  * Si la acción carece de patrón, la acción se ejecutará para todas las líneas de entrada. 
 +  * Si un patrón carece de acciónla línea coincidente se devolverá como //salida// (una linea con muchos patrones coincidentes será impresa varias veces).
  
-Como en las declaraciones de awk tanto los patrones como acciones resultan opcionales, como forma de distinguir unos de otras, son las acciones las que se encierran entre llaves ''{}''.+Naturalmente, las líneas cuyos patrones no resultan en coincidencia, son ignoradas ("filtradas").
  
 +Pueden disponerse comentarios en los programas de awk (los cuales también resultan filtrados). Estos comienzan con el carácter ''#'' y finalizan con el final de la línea, como en 
 +
 +<code awk>
 +patron { acción } # Este es el comentario de la linea.
 +</code>
 ====Registros y Campos==== ====Registros y Campos====
  
Línea 51: Línea 50:
 Las variables ''FS'' y ''RS'' refieren al //separador de campo// y //separador de registro//. Estos pueden ser asignadas en cualquier momento por un único caracter. Por ejemplo, para asignar el caracter ''c'' como separador de campo en la variable ''FS'', se utiliza el argumento opcional de línea de comandos ''-Fc''. Las variables ''FS'' y ''RS'' refieren al //separador de campo// y //separador de registro//. Estos pueden ser asignadas en cualquier momento por un único caracter. Por ejemplo, para asignar el caracter ''c'' como separador de campo en la variable ''FS'', se utiliza el argumento opcional de línea de comandos ''-Fc''.
  
-En caso que el separador de registro esté vacío, se considera como separador de registro por defecto a una línea vacía, y los caracteres en blanco, tabuladores y nuevas líneas se consideran como separadores de campo por defecto.+En caso que el separador de registro esté vacío, se considera como separador de registro por defecto a una //línea vacía//, y los //separadores de campo// por defecto son los //caracteres en blanco// (''tabulación'' ''nuevas línea''se consideran como.
  
-La variable ''FILENAME'' contiene el nombre del fichero de entrada actual. +La variable ''FILENAME'' se utiliza para contener el nombre del fichero de entrada actual.
-====Uso====+
  
  
 +=====Patrones=====
  
-Un ejemplo de un programa awk que imprime la tercera y segunda columna de una tabla en dicho orden: +Un //patrón// en frente de una acción opera como un **semáforo que __determina si la acción debe ejecutarse__**
- +
-<code awk>[print $3; $2]</code> +
- +
-Este imprime todas las líneas de entradas con una A, B, o C en el segundo campo: +
- +
-<code awk>$2 ~/A|B|C/]</code> +
- +
-Este imprime todas las líneas en las cuales el primer campo es diferente que el primer campo previo: +
-<code awk>$2 ~/A|B|C/]</code> +
- +
- +
- +
-El comando  +
-<code awk>awk programa [ficheros]</code> +
-ejecuta los comandos de awk en la cadena ''programa'' sobre el conjunto de ficheros especificxados, o en la entrada estándar si no hubiese ficherosLa declaración también puede colocarse en un ''fichero_salida'' con el comando: +
- +
-<code awk>awk -f fichero_salida [ficheros]</code>+
  
 +Como patrón podrán utilizarse una variedad de expresiones de control: [[#expresiones regulares de awk|expresiones regulares]], [[#expresiones relacionales de awk|expresiones relacionales aritméticas]], expresiones de cadena, y combinaciones booleanas arbitrarias.
  
-===Impresión====+====Print====
  
-Una acción puede carecer de patrón, en cuyo caso la acción se ejecutará para todas las líneas. La acción más simple es imprimir algo o todo de de un registro; esto se realiza con el comando print de awk.+La acción más simple consiste imprimir algo o todo de de un registro; esto se realiza con el comando ''print'' de awk.
  
 El siguiente comando imprime todas los registros, copiando la entrada a la salida de forma intacta. El siguiente comando imprime todas los registros, copiando la entrada a la salida de forma intacta.
Línea 86: Línea 69:
 <code awk>{ print }</code> <code awk>{ print }</code>
  
-Más útil es imprimir un campo o campos de cada registro, por ejemplo, imprimir los priermos dos campos en orden inverso:+Resulta más útil imprimir un campo o campos de cada registro, por ejemplo, imprimir los primeros dos campos en orden inverso:
  
 <code awk>print $2, $1</code> <code awk>print $2, $1</code>
Línea 98: Línea 81:
 <code awk>{ print NR, NF, $0 }</code> <code awk>{ print NR, NF, $0 }</code>
  
-La salida puede divirise en múltiples ficheros, por ejemplo el programa siguiente escribe el primer campo ''$1'' en ''fichero1'' y el segundo campo en el ''fichero2''+La salida puede dividiise en múltiples ficheros, por ejemplo el programa siguiente escribe el primer campo ''$1'' en ''fichero1'' y el segundo campo en el ''fichero2''
  
 <code awk>{ print $1 >"fichero1"; print $2 >"fichero2" }</code> <code awk>{ print $1 >"fichero1"; print $2 >"fichero2" }</code>
Línea 115: Línea 98:
 envía por correo electrónico la salida a bwk. envía por correo electrónico la salida a bwk.
  
-Las variables ''OFS'' y ''ORS'' pueden utilizarse para cambiar el separador de campo de salida y el separador de registro de salida. El separador de registro de salida se agrega a la salida de la declaración print.+Las variables ''OFS'' y ''ORS'' pueden utilizarse para cambiar el separador de campo de salida y el separador de registro de salida. El separador de registro de salida se agrega a la salida de la declaración ''print''.
  
 Awk también provee a la declaración printf para formateado de salida, con esta sintaxis: Awk también provee a la declaración printf para formateado de salida, con esta sintaxis:
Línea 125: Línea 108:
 <code awk>printf "%8.2f %10ld\nm $1, $2</code> <code awk>printf "%8.2f %10ld\nm $1, $2</code>
  
-=====Patrones===== 
  
-Un patrón en frente de una acción opera como un **selector que determina si la acción debe ejecutarse**. Pueden utilizarse una variedad de expresiones como patrones: [[#expresiones regulares de awk|expresiones regulares]], [[#expresiones relacionales de awk|expresiones relacionales aritméticas]], expresiones de cadena, y combinaciones booleanas arbitrarias.+---- 
 +Un ejemplo de un programa awk que imprime la tercera y segunda columna de una tabla en dicho orden: 
 + 
 +<code awk>[print $3; $2]</code> 
 + 
 +Este imprime todas las líneas de entradas con una ''A'', ''B'', o ''C'' en el segundo campo: 
 + 
 +<code awk>$2 ~/A|B|C/]</code> 
 + 
 +Este imprime todas las líneas en las cuales el primer campo es diferente que el primer campo previo: 
 +<code awk>$2 ~/A|B|C/]</code>
  
  
Línea 174: Línea 166:
 El circunflejo ''ˆ'' refiere al comienzo de la línea o campo, mientras que el signo pesos ''$'' refderirá al final de línea o campo. El circunflejo ''ˆ'' refiere al comienzo de la línea o campo, mientras que el signo pesos ''$'' refderirá al final de línea o campo.
  
-===Expresiones Relacionales de awk === +====Expresiones Relacionales de awk ==== 
-Los patrones de awk pueden ser expresiones relacionales que incluyan los operadores relacionales convencionales ''<'', ''<='', ''=='', ''!='', ''>='', y ''>''. Un ejemplo es ''$2 > $1 + 100'' que seleccionará las líneas donde el segundo campo es al menos un ''100'' mayor que el primer campo. De forma similar,+Los patrones de awk pueden ser expresiones relacionales que incluyan los [[operadores en unix#operadores relacionales|operadores relacionales convencionales]] ''<'', ''<='', ''=='', ''!='', ''>='', y ''>''. Un ejemplo es ''$2 > $1 + 100'' que seleccionará las líneas donde el segundo campo es al menos un ''100'' mayor que el primer campo. De forma similar,
  
 <code awk>NF % 2 == 0</code> <code awk>NF % 2 == 0</code>
Línea 192: Línea 184:
  
  
-===Patrones Combinacionales=== +====Patrones Combinacionales==== 
-Un patrón puede ser cualquier patrones combinacinoal booleanos OR ''||'', AND ''&&'', y NOT ''!''+Un patrón puede ser cualquier operador [[operadores en unix#operadores lógicos|combinacinoal de lógica booleana]] OR ''||'', AND ''&&'', y NOT ''!''
  
 Por ejemplo, este programa de awk selecciona las líneas donde un primer campo comienza con ''p'', pero no sea ''perez''. El ''&&'' y el ''||'' garantizan que sus operandos sean evaluados de izquierda a derecha; la evaluación se detendrá tan pronto como se verifique verdad o falsedad. Por ejemplo, este programa de awk selecciona las líneas donde un primer campo comienza con ''p'', pero no sea ''perez''. El ''&&'' y el ''||'' garantizan que sus operandos sean evaluados de izquierda a derecha; la evaluación se detendrá tan pronto como se verifique verdad o falsedad.
Línea 199: Línea 191:
 <code awk>$1 >= "p" && $1 < "q" && $1 != "perez"</code> <code awk>$1 >= "p" && $1 < "q" && $1 != "perez"</code>
  
-===Rangos de Patrones===+====Rangos de Patrones====
  
 El ''patrón'' que selecciona una acción puede consistir de dos patrones separados por '','', siguiendo la sintaxis El ''patrón'' que selecciona una acción puede consistir de dos patrones separados por '','', siguiendo la sintaxis
Línea 211: Línea 203:
 Dichas declaraciones de acción pueden utilizarse para realizar una variedad de **tareas de manipulación de cadenas o de registro**. Dichas declaraciones de acción pueden utilizarse para realizar una variedad de **tareas de manipulación de cadenas o de registro**.
  
-==== Funciones Incorporadas====+Las declaraciones pueden ser una de las siguientes: 
 + 
 +  * Declaración ''if (expresión) [declaración else]'' 
 +  * Declaración ''while (expresión)'' 
 +  * Declaración ''for (expreión; expresión; expresión)'' 
 +  * Declaración ''for (var en array)'' 
 +  * Declaración ''do'' ''while (expresión)'' 
 +  * ''break'' 
 +  * ''continue'' 
 +  * ''<nowiki>{ [declaración ...] }</nowiki>'' 
 +  * ''expression'' (conmunmente ''var = expression'' 
 +  * ''<nowiki>print [expresión-lista] [>expression]</nowiki>'' 
 +  * ''printf format [..., expresión-lista] [>expresión]'' 
 +  * ''return [expresión]'' 
 +  * ''next'' (saltea los patroners remanentes de esta línea de entrada) 
 +  * ''nextfile'' (saltea lo siguiente en este fichero, abre el siguiente, comienza desde arriba) 
 +  * ''delete array[expression]'' (borra un elemento del array) 
 +  * ''delete array'' (borra todos los elementos del array) 
 +  * ''exit [expresión]'' (sale del procesado y realiza procesado ''END''; el status será ''expresión''
 + 
 +==== Funciones Incorporadas ====
 Awk incorpora la función ''lenght'' para computar la longitud de una cadena de caracteres. Este programa imprimirá cada registro, precedido por su longitud: Awk incorpora la función ''lenght'' para computar la longitud de una cadena de caracteres. Este programa imprimirá cada registro, precedido por su longitud:
  
Línea 240: Línea 252:
 ...pondrá la ''x'' a una cadena producida por el formateo de los valores de ''$1'' y ''$2''. ...pondrá la ''x'' a una cadena producida por el formateo de los valores de ''$1'' y ''$2''.
  
-=== Variables, Expresiones, y Asignaciones===+==== Variables, Expresiones, y Asignaciones====
  
 Las variables de awk toman valores numéricos (coma flotante) o cadenas alfabéticas de acuerdo al contexto. Por ejemplo, en ''x = 1'', ''x'' es claramente una cifra, mientras que en ''x = "perez"'' es claramente una cadena alfanumérica. Las cadenas se convierten a números y viceversa, toda vez que el contexto lo demande. Por ejemplo: Las variables de awk toman valores numéricos (coma flotante) o cadenas alfabéticas de acuerdo al contexto. Por ejemplo, en ''x = 1'', ''x'' es claramente una cifra, mientras que en ''x = "perez"'' es claramente una cadena alfanumérica. Las cadenas se convierten a números y viceversa, toda vez que el contexto lo demande. Por ejemplo:
Línea 248: Línea 260:
 ...asigna ''7'' a la ''x'' ...asigna ''7'' a la ''x''
  
-Las cadenas que no pueden ser intepretadas numéricamente en un contexto numérico generalmente tienen un valor numérico de ''0'', pero no suele ser adecuado contar siguiendo este comportamiento.+Las cadenas que no pueden ser interpretadas numéricamente en un contexto numérico generalmente tienen un valor numérico de ''0'', pero no suele ser adecuado contar siguiendo este comportamiento.
  
 Por defecto las demás variables que no son las incorporadas, deben inicializarse a una cadena nula, que tiene un valor numérico de ''0''; esto elimina la necesidad de la mayoría de las secciones de tipo ''BEGIN''. Por ejemplo, la sima de los primeros dos campos puede computarse con: Por defecto las demás variables que no son las incorporadas, deben inicializarse a una cadena nula, que tiene un valor numérico de ''0''; esto elimina la necesidad de la mayoría de las secciones de tipo ''BEGIN''. Por ejemplo, la sima de los primeros dos campos puede computarse con:
Línea 262: Línea 274:
  
 ====Variables de Campo==== ====Variables de Campo====
-Los campos en awk comparten escencialmente todas las propiedades de las variables: puedeb usarse en artimética u operaciones de cadenas, y también pueden ser asignados. Por lo tanto puede reemplazarse el primer campo con un número de secuencia: +Los campos en awk comparten esencialmente todas las propiedades de las variables: pueden usarse en aritmética u operaciones de cadenas, y también pueden ser asignados. Por lo tanto puede reemplazarse el primer campo con un número de secuencia:
-Fields in awk share essentially all of the properties of variables — they may be used in arithmetic+
  
 <code awk>{ $1 = NR; print }</code> <code awk>{ $1 = NR; print }</code>
  
-...o acumular dos campos en un tercero, así:+...o bien acumular dos campos en un tercero, así:
  
 <code awk>{ $1 = $2 + $3; print $0 }</code> <code awk>{ $1 = $2 + $3; print $0 }</code>
  
-...o bien asignar una cadena a un campo:+...o incluso asignar una cadena a un campo:
  
 <code awk> <code awk>
Línea 305: Línea 316:
 ...imprime los dos campos separados por ''" es "''. Las variables y expresiones numéricas también pueden aparecer en las concatenaciones. ...imprime los dos campos separados por ''" es "''. Las variables y expresiones numéricas también pueden aparecer en las concatenaciones.
  
-====Vectores de awk====+====Arreglos de awk====
 Los elementos de los //arreglos// de awk no necesitan ser declarados; activan su existencia simplemente por ser mencionados. Los subscriptos pueden tener cualquier valor no nulo, incluyendo cadenas no numéricas. Como ejemplo de un subscripto convencional, la declaración Los elementos de los //arreglos// de awk no necesitan ser declarados; activan su existencia simplemente por ser mencionados. Los subscriptos pueden tener cualquier valor no nulo, incluyendo cadenas no numéricas. Como ejemplo de un subscripto convencional, la declaración
  
Línea 370: Línea 381:
 La declaración ''next'' provoca que awk saltee inmediatamente al segundo registro y cominece a analizar los patrones desde el inicio. La declaración ''exit'' provoca que el programa se comporte como si hubiese ocurrido la finalización de la entrada. La declaración ''next'' provoca que awk saltee inmediatamente al segundo registro y cominece a analizar los patrones desde el inicio. La declaración ''exit'' provoca que el programa se comporte como si hubiese ocurrido la finalización de la entrada.
  
-Pueden disponerse comentarios en los programas de awk: comienzan con el caracter ''#'' y finalizan con el final de la línea, como en  
  
-<code awk> 
-print x, y # Esto es un comentario de línea. 
-</code> 
  
  
-==== Variables de campo ==== 
  
------ 
- 
- 
-Analiza cada fichero de entrada en búsqueda de coincidencias con conjunto de patrones dados. Estos pueden ser especificados literalmente en forma de programación, o a través de uno o más ficheros de guiones específicados. 
- 
-En cada patrón puede existir una acción asociada a realizar, no bien una línea del fichero coincida con el patrón. Cada línea es analizada en búsqueda de coincidencias de cada declaración patrón-acción; la acción asociada se realiza allí. El nombre de fichero ''-'' singnifica entrada estándar. Cualquier fichero de la forma variable-valor será tratado como asignación, no un nombre de fichero, y se ejecuta al tiempo en que se hubiese abierto si fuese un fichero. 
- 
- 
-La //entrada// normalmente está conformada por //líneas de entrada// (registros), o bien por el valor de RS. Si el RS es nulo, las líneas en blanco se utilizan como separadores de registro, y las líneas se usan como separadores de campo (además del valor de FS). Esto resulta conveniente al trabajar con registros multilíneas. 
- 
-En las **líneas de entrada**, los //campos// resultan divididos por espacios en blancos, o bien por el caracter valor designado como //separador de campo// ''FS'' al leer la línea. Los **campos** se designan ''$1'', ''$2'', ..., (''$0'' refiere a la línea completa). 
- 
-El separador de campo ''FS'' puede ser un caracter simple, o una [[expresiones regulares|expresión regular]]. Como caso especial, si FS es un espacio en blanco (su opción por defecto), los campos serán divididos por uno o más caracterers en blanco. Si el ''FS'' es nulo, la línea de entrada se dividi en un campo por caracter. 
- 
-Los campos pueden separarse normalmente por cualquier cantidad de caracteres en blanco. Para establecer un separador de campo como un espacio en blanco simple, debe usarse la opción ''-F'' con un valor de ''[ ]''. Para especificar un caracter de tabulador como separador de campo, debe indicarse ''/t'' o bien ''t'' 
- 
-El separador de campo se configura usualmente vía la opción ''-F'' o desde el bloque ''BEGIN'', de modo que toma efecto antes de que se lea la entrada. 
- 
-Una declaración patrón-acción guarda la siguiente sintaxis: 
- 
-<code awk>patrón { acción }</code> 
- 
-Si no se provee una ''{ acción}'', se imprimirá la línea. Si no se provee un ''patrón'', siempre habrá coincidencias. Las declaración patrón-acción deben ponerse en líneas separadas, o separarse con '';''. 
- 
-Se permiten nuevas líneas luego de una declaración de finalización, o siguiento una '','', una ''{'' o un AND lógico (''&&'') o un OR lógico (''||'')., luego de las instrucciones ''do'' o ''else'', o luego del '')'' de las declaraciones ''if'', ''for'' o ''while''. Además, la ''<nowiki>\</nowiki>'' puede utilizarse para anular el significado interpretado de nua nueva línea entre las declaraciones patrón-acción. 
- 
-Una **acción** de awk es una secuencia de declaraciones. 
- 
-Las declaraciones pueden ser una de las siguientes: 
- 
-  * Declaración ''if (expresión) [declaración else]'' 
-  * Declaración ''while (expresión)'' 
-  * Declaración ''for (expreión; expresión; expresión)'' 
-  * Declaración ''for (var en array)'' 
-  * Declaración ''do'' ''while (expresión)'' 
-  * ''break'' 
-  * ''continue'' 
-  * ''<nowiki>{ [declaración ...] }</nowiki>'' 
-  * ''expression'' (conmunmente ''var = expression'' 
-  * ''<nowiki>print [expresión-lista] [>expression]</nowiki>'' 
-  * ''printf format [..., expresión-lista] [>expresión]'' 
-  * ''return [expresión]'' 
-  * ''next'' (saltea los patroners remanentes de esta línea de entrada) 
-  * ''nextfile'' (saltea lo siguiente en este fichero, abre el siguiente, comienza desde arriba) 
-  * ''delete array[expression]'' (borra un elemento del array) 
-  * ''delete array'' (borra todos los elementos del array) 
-  * ''exit [expresión]'' (sale del procesado y realiza procesado ''END''; el status será ''expresión'') 
- 
-Las declaraciónes deben finalizarse con '';'', fin de línea o ''}''. Una expresión-lista vacía corresponde a ''$0''. Las constantes de cadena se ponen entre ''""'', y se reconocen los escapes usuales del lenguaje C. Las expresiones tomas una cadena o valores numéricos, y se construyen con los operadores  ''+'' ''-'' ''*'' ''/'' ''%'' ''^''. Los operadores   ''!'' ''++'' ''--'' ''+='' ''-='' ''*='' ''<nowiki>/=</nowiki>'' ''%='' ''^='' ''<nowiki>></nowiki>'' ''<nowiki>>=</nowiki>'' ''<nowiki><</nowiki>'' ''<nowiki><=</nowiki>'' ''=='' ''!='' y ''?:''  también se usan en las expresiones. 
- 
-Las variables pueden ser escalares, elementos de arrays (denotamos como ''x'' o campos). Las variaables se inicializan en la cadena nula. Los arrays subscriptos pueden ser cualquier cadena, no necesaria numéricas; esto permite una forma de memoria asociativa. Se permiten los múltiples subcritos como ''[i,j,k]'', sus constituyentes son concatenados, separados por el valor de ''SUBSEP'' 
- 
-===Print=== 
- 
-La declaración ''print'' presenta sus argumentos en la salida estándar (o en un fichero utilizando los operadores ''>'' o ''>>'' en un caño si se utiliza ''| comando'', separado por el separador de campo de salida, y terminado por el separador de registro de salida. 
- 
-Los ficheros con comandos puedes ser nombres literales o ''(expresion)''; los valores de cadena idénticos en declaraciones diferentes denotan al mismo fichero abierto. La declaración ''printf'' formatea su lista de expresión de acuerdo al formato. 
- 
-====Patrones==== 
-Los patrones son combinaciones booleanas arbitrarias (con ''!'' ''||'' ''&&'' or expresiones regulares y expresiones relacionales. awk soporta [[expresiones regulares#expresiones regulares extendidas|expresiones regulares extendidas]]. 
- 
-Las expresiones regulares aisladas en un patrón se aplican a la línea entera. Estas pueden ocurrir en las expresiones relacionales cuando utilizando los operadores ''~'' y ''!~''. ''<nowiki>/re/</nowiki>'' es una expresión constante regular; puede utilizarse  cualquier cadena (constante o variable) como una expresión regular, con excepción de la posición de una expresión regular aislada en un patrón. 
- 
-Un patrón puede consistir de dos patrones separados por '',''; en tal caso, la acción se desarrolla para todqas las líneas desde la primer ocurrencia del patrón a través de las ocurrencias del segundo. 
- 
-====Expresión relacional==== 
-Una expresión relacional puede cobrar una de las siguientes formas: 
- 
-  * ''expresión matchop expresión-regular'' 
-  * ''expresión relop expression'' 
-  * ''expresión en nombre-array'' 
-  * ''(expr, expr, ...) en nombre-array'' 
- 
-donde una ''relop'' es cualquiera de los operadores relacionales en C, y un ''matchop'' es ya sea un ''~'' (coindidencia) o ''!~'' (no coincidencia). Un condicional es una expresión aritmética, una expresión relacional, o una combinación booleana de estas. 
- 
-El patrón especial ''BEGIN'' puede utilizarse para capturar conrtol antes de que la primera línea de entrada sea leída. El patrón especial ''END'' puede ser utilizado para capturar control luego de que el procesado sea finalizado. ''BEGIN'' y ''END'' no pueden combinarse con otros patrones. Pueden aparecer en múltiples ocasiones en un programa, y ejecutarse en el orden que son leídos por awk. 
- 
-====Variables==== 
-Nombres de las variables de awk. 
- 
-| ''ARGC'' | Contaror de aumento, asignable. | 
-| ''ARGV'' | Array de automento, asignable; números no nulos resultan consideredos nombres de fichero. | 
-| ''CONVFMT'' | Formato de conversión cuando se convierten números (por defecto ''%.6g?''). | 
-| ''ENVIRON'' | Array de variables de ambiente; los subscriptos son nombres. | 
-| ''FILENAME'' | El nombre del fichero de entrada actual. | 
-| ''FNR'' | Número ordinal del registro actual en el fichero actual. | 
-| ''FS'' | Expresión regular utilizada para separar campos (por defecto espacios en blanco); también seteable a través de la opción ''-F fs''. | 
-| ''NF'' | Cantidad de campos en el registro actual. Puede usarse ''$NF'' para obtener el valor del último campo en el registro actual. | 
-| ''NR'' | Número ordinal del registro actual. | 
-| ''OFMT'' | Formato de salida para los números (por defecto ''%.6g''). | 
-| ''OFS'' | Separador del campo de salida (por defecto carácter en blanco)). | 
-| ''ORS'' | Separador del registro de salida (por defecto nueva línea). | 
-| ''RLENGTH'' | El largo de la cadena en búsqueda de coincidencia por la función ''match()''. | 
-| ''RS'' | Separador del registro de entrada (por defecto nueva línea). Si está vacío, las líneas en blanco separan registros. Si hay mas de un carácter en su extensión el ''RS'' se trata como una expresión regular, y los registros resultan separados por el texto que coincida con la expresión dada. | 
-| ''RSTART'' | La posición de inicio de la cadena coincidente con la función ''match()''. | 
-| ''SUBSEP'' | Separa múltiples suscriptos (por defecto ''034''). | 
-====Funciones==== 
-===Funcinoes Aritméticas=== 
-===Funciones de Cadena=== 
-===Funciones de tiempo === 
-===Funciones de E/S y Generales=== 
- 
- 
- 
- 
- 
----- 
- 
- 
-EL awk es un poderoso lenguaje de programación que en muchas ocasiones nos sacara de apuros a la hora de tener que hacer script complejos de tratamiento de texto. El awk al igual que el sed lee las líneas completas para realizar sus modificaciones. Uno de los aspectos mas útiles en relación al awk es que a diferencia del [[sed]], awk puede dividir las líneas en campos a través de un separador de campo indicado en el guion o en la línea de comandos. Si no se indica ninguno se tomara como separador de campo un espacio o tabulador. Usando la opción ''-F'' de la línea de comandos o la variable ''FS'' desde un programa hecho en awk se puede especificar un nuevo separador de campo. Por ejemplo si lo que quisiéramos es ver los nombres verdaderos que aparecen en el archivo ''/etc/passwd'' primero tendríamos que saber como separar los campos. En el archivo ''/etc/passwd'' se separan por un '':''. Ahora tendríamos que saber en que campo se encuentra el nombre. Es en el campo numero ''5'', comenzando a contar como el primero de los campos. El ''0'' es la línea completa y ya veremos por que 
- 
-<code bash>$ cat /etc/passwd | awk -F : '{print $5}'</code> 
- 
-<code> 
-root 
-bin 
-daemon 
-adm 
-lp 
-sync 
-shutdown 
-halt 
-mail 
-news 
-uucp 
-operator 
-games 
-gopher 
-FTP 
-User 
-Nobody 
-X Font Server 
-Named 
-PostgreSQL Server 
-Shrek Ogre 
-Fiona Ogre 
-</code> 
- 
-Como vemos lo primero que hicimos fue indicarle al awk cual seria el separador de campo ''-F :'', luego entre comillas le indicamos que imprima a la salida estándar el campo nº 5, ''<nowiki>'{print $5}'</nowiki>''. De esta forma vemos los nombres contenidos en el archivo ''/etc/passwd''. Podríamos imprimir mas de un campo a la vez, por ejemplo si queremos mostrar también el directorio home de cada uno de los usuarios podríamos hacer lo siguiente: 
- 
-<code bash>cat /etc/passwd | awk -F : '{print $5,$6}'</code> 
- 
-<code> 
-root /root 
-bin /bin 
-daemon /sbin 
-adm /var/adm 
-lp /var/spool/lpd 
-. . . 
-PostgreSQL Server /var/lib/pgsql 
-Shrek Ogre /home/shrek 
-Fiona Ogre /home/fiona 
-</code> 
- 
-De esta simple manera podremos ir completando la línea a los requerimientos del campo que queramos ver ya que tenemos la posibilidad de hacer comparaciones a un campo de la misma manera que la haríamos a una variable en cualquier otro lenguaje. Por ejemplo si quisiéramos ver las líneas del ''/etc/passwd'' de todos aquellos usuarios que pertenecen al grupo ''user'', representado por el nº 100 en el archivo ''passwd'', podríamos hacer que el awk comprara el número del campo en el que esta el número GUID que nosotros buscamos. En el caso particular que cada usuario tuviese su grupo, podríamos hacer que se compararan todas las líneas que posean un número mayor o igual al número de grupo de usuarios mas bajo, por ejemplo 500 es el número que por defecto pone Linux a al grupo del primer usuario y va incrementándose a medida que incorporamos usuarios. Tendríamos que mostrar todas las líneas que en campo donde esta el GUID, el número 4, del usuario y que sea mayor o igual a 500. Por ejemplo: 
- 
-<code>cat /etc/passwd | awk -F :\</code> 
- 
-<code awk> 
-'$4>=500 {print $0}' 
-shrek:x:500:500:Shrek Ogre:/home/shrek:/bin/bash 
-fiona:x:501:501:Fiona Ogre:/home/fiona:/bin/bash 
-</code> 
- 
-Como verán se indico que mostrara solo aquellas líneas que tuviesen en el campo nº 4 un valor mayor o igual a 500, ''$4>=500''.También se ve que mostramos la línea entera al poner como campo a imprimir el ''$0''. Una acotación que tendríamos que notar. Lo que comparamos en esta oportunidad es un número y esto lo hace tremendamente poderoso al awk como lenguaje de programación. Si se quisieran compara cadenas, se tendrían que encerrar ente ''""''. Como ejemplo, si hubiésemos encerrado entre ''""'' al 500 lo que awk interpretaría es que queremos mostrar todas las líneas que en la posición ''4'' tengan un valor alfabéticamente mayor o igual a ''500''. 
- 
-<code bash>cat /etc/passwd | awk -F :\</code> 
-<code> 
-'$4>="500" {print $0}' 
-lp:x:4:7:lp:/var/spool/lpd: 
-nobody:x:99:99:Nobody:/: 
-shrek:x:500:500:Shrek Ogre:/home/shrek:/bin/bash 
-fiona:x:501:501:Fiona Ogre:/home/fiona:/bin/bash 
-</code> 
- 
-Como verán si se ordena alfabéticamente la posición ''4'' el ''7'' y el ''99'' son mayores que ''500''. Los operadores que awk puede manejar son los siguientes: 
- 
-===Operadores de Awk=== 
-| Operador | Significado | 
-| ''<'' | menor que | 
-| ''<='' | menor que o igual que | 
-| ''=='' | igual a | 
-| ''!='' | no igual a | 
-| ''>='' | mayor que o igual que | 
-| ''>'' | mayor que | 
- 
-Otra posibilidad es el usar expresiones regulares para efectuar la búsqueda. Pero cuidado ya que es tienen que ser ingresadas de acuerdo a sí es mayúscula o minúscula. 
- 
->code bash>cat /etc/passwd | awk -F :\</code> 
-<code> 
-'/Shrek/ {print $0}' 
-shrek:x:500:500:Shrek Ogre:/home/shrek:/bin/bash 
-</code> 
- 
-Lo único que tendremos que hacer es encerrarlo entre ''/'' para que se tomen como expresión regular. Ahora bien, las expresiones podrán ser tan complejas como queramos. Por ejemplo si quisiéramos mostrar todas las líneas que tuviesen la cadena ''se'' pero que no tengan antes la letra ''U'' y no les siga un espacio la orden es 
- 
-<code bash>cat /etc/passwd | awk -F :\</code> 
-<code awk> 
-'/[^U]se[^ ]/ {print $0}' 
-shrek:x:500:500:Shrek Ogre:/home/shrek:/bin/bash 
-</code> 
- 
-Como ven las cadenas que tenemos que ignorar se preceden antes y después de la cadena buscada ingresando un símbolo ''^'' encerrado entre ''[]''. De esta manera se podrá ir usando las distintas expresiones regulares. En todos estos casos se utilizaron una única forma para imprimir en pantalla los resultados, pero es bueno saber que contamos con otra forma en la que podremos formatear el texto antes de su salida por pantalla. Para la salida formateada se utiliza el ''printf''. Por ejemplo si quisiéramos podríamos imprimir los datos en una forma más cómoda: 
- 
-<code bash>cat /etc/passwd | awk -F :\</code> 
-<code awk> 
-'$4>=500 {printf"%20s %5s\n",$5,$1}' 
-Shrek Ogre shrek Fiona Ogre fiona 
-</code> 
- 
-Como se puede ver, pedimos que nos mostrara el nombre completo de l usuario y el nombre de usuario. Como sabemos la extensión aproximada que tendrá cada campo le damos 20 posiciones para le primer campo a mostrar, el $5, y 5 posiciones para el segundo campo a mostrar, el ''$1''. Si lo que quisiéramos mostrar fuesen número en lugar de la ''%s'' (string) iría una ''%d'' o ''%i'' (decimal). Para mas información sobre el printf buscar en las páginas de manual del awk. Existen diferentes variables integradas, a parte del ''FS'', que permiten llevar cuentas de distintos aspectos. Por ejemplo existe la variable ''NR'' que llevara la cuenta de los registros que mostremos. Por ejemplo supongamos que necesitamos obtener un listado largo de un directorio, pero solo queremos ver los permisos, el nombre del archivo y el número de registro que a pasado por el awk. 
- 
-<code bash>ls -l | awk '{ print NR" "$1" "$9}'</code> 
-<code> 
-1 total 
-2 -rw-rw-r-- 146768 
-3 -rw-rw-r-- Bienvenidos 
-4 -rw-rw-r-- Bienv 
-5 -rw-rw-r-- authkey.file 
-6 drwxr-xr-x Desktop 
-7 -rw-rw-r-- LUGRo 
-8 drwxrwxr-x Linux 
-9 -rw-rw-r-- Listado 
-10 -rw-rw-r-- Lo 
-11 drwx------ Mail 
-. . . 
-49 -rw-rw-r-- pgaccess-report.ps 
-50 -rw-rw-r-- sed 
-51 -rw-rw-r-- sed.zip 
-52 -rw-rw-r-- smtptel.htm 
-53 -rw-rw-r-- vicky  
-</code> 
- 
-Como verán, en esta ocasión la variable NR fue llevando la cuenta de los registros que fueron pasando por el awk. De esta forma se podrá decirle al awk que me muestre de los registros 5 al 10 solamente. scr Existen muchas más variables en el awk que son de extrema utilidad. Por ejemplo, en el caso anterior sabíamos que el ultimo campo estaba en la posición número ''9'', pero ¿que ocurre si no sabemos la posición del último campo o esta varia? Para esto esta la variable ''NF'' que lleva la cuenta de la cantidad de campos de cada registro. Por ello en lugar de la anterior forma podríamos poner: 
- 
-<code bash>ls -l | awk '{ print NR" "$1" "$NF}'</code> 
- 
-y obtendríamos idénticos resultados. Pero un momento, aquí hay algo raro. La variable NR no tiene el signo $, en cambio la variable NF si lo tiene. Esto esta dado así para que no se reemplazado por el awk. Por ejemplo si hubiésemos puesto la variable NF sin signo $ el resultado seria. 
- 
-<code bash>ls -l | awk '{ print NR" "$1" "NF}'</code> 
-<code> 
-1 total 2 
-2 -rw-rw-r-- 9 
-3 -rw-rw-r-- 11 
-4 -rw-rw-r-- 11 
-5 -rw-rw-r-- 11 
-6 drwxr-xr-x 9 
-. . .  
-</code> 
- 
-Lo que nos esta mostrando no es el último campo, sino la cantidad de campos que ese registro tiene. Al agregarle el signo ''$'' se reemplazara con el número del último campo y ese campo el que será mostrado. Esto es así para todas las variables integradas. El awk puede ser usado no-solo en una línea. Podríamos usarlo también como cualquier otro lenguaje para realizar múltiples tareas en una línea o realizar algo antes de comenzar la lectura y otra después. Para demarcar el código se utiliza los pares BEGIN-END. Todo lo que aparece después de la palabra ''BEGIN'', pero en el mismo renglón, se realiza antes de que comience el ciclo. Cualquier cosa que este después de ''END'' se realiza después de que se haya leído la última línea y cerrado el ciclo. Estas líneas tendrán que estar en un archivo que será utilizado por el awk para procesar en este ejemplo al archivo ''/etc/passwd''. Un ejemplo seria el siguiente: 
- 
-<code awk> 
-BEGIN { FS=":"} 
-{ printf"Nombre Completo: %s\n",$5 } 
-{ printf"Nombre de Usuario: %s\n",$1} 
-{ printf"UID: %i,GUID: %i\n\n",$3,$4 } 
-END { printf "\n\nTotal de usuarios: %d \n\n", NR} 
-</code> 
- 
-Este pequeño programa realizado con el vi será guardado en el archivo ''awk.src'', el nombre se lo damos nosotros, y nos servirá para mostrar algunos datos del ''/etc/passwd'' mas detalladamente. La forma de ejecutarlo es a través del modificado "-f" donde le decimos al awk que a continuación le pasaremos un archivo con el programa que tiene que usar para procesar el ''/etc/passwd''. 
- 
-<code bash>awk -f awk.src /etc/passwd</code> 
-<code> 
-Nombre Completo: root Nombre de Usuario: root UID: 0,GUID: 0 
-Nombre Completo: bin Nombre de Usuario: bin UID: 1,GUID: 1 
-Nombre Completo: daemon Nombre de Usuario: daemon UID: 2,GUID: 2 
-Nombre Completo: adm Nombre de Usuario: adm UID: 3,GUID: 4 
-. . . 
-Nombre Completo: PostgreSQL Server Nombre de Usuario: postgres UID: 26,GUID: 26 
-Nombre Completo: Shrek Ogre Nombre de Usuario: shrek UID: 500,GUID: 500 
-Nombre Completo: Fiona Ogre Nombre de Usuario: fiona UID: 501,GUID: 501 
-Total de usuarios: 22 
-</code> 
- 
-Para finalizar diremos que también se podrán hacer operaciones con estas variables, es decir, sumarlas restarlas, multiplicarlas y dividirlas. Por ejemplo si quisiéramos saber en cuantos bloques de 4 líneas podríamos formar con un archivo de texto dado podríamos hacer el siguiente programa: 
- 
-<code awk> 
-BEGIN {FS=":"} 
-{ print $0 } 
-FNR%4==0 { printf"\n" } 
-END { printf "El archivo %s puede entrar en %i bloques enteros\ 
- de 4 lineas\n",FILENAME,NR/4} 
-</code> 
- 
-Existen un par de cosas nueva en el. Por ejemplo la variable ''FNR'' que cuenta el número de líneas. En esta ocasión le estamos diciendo que si el modulo de FNR es igual a 4 ''FNR%4'' imprima un salto de linea ''{ printf"\n" }''. Y al finalizar el ciclo se mostrara el mensaje que nos informara cuantos bloques de 4 líneas podremos tener. Para obtener el resultado se efectúa una división del numero total de registros ''NR'' por el número de líneas que queremos armar el bloque, ''4''. La variable FILENAME indica cual es el archivo sobre el cual se realizo el proceso y es tomada cuando se la pasamos al awk como argumento. El resultado es 
- 
-<code bash>awk -f awk2.src /etc/passwd</code> 
- 
-<code> 
-root:x:0:0:root:/root:/bin/bash 
-bin:x:1:1:bin:/bin: 
-daemon:x:2:2:daemon:/sbin: 
-adm:x:3:4:adm:/var/adm: 
-lp:x:4:7:lp:/var/spool/lpd: 
-sync:x:5:0:sync:/sbin:/bin/sync 
-shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 
-halt:x:7:0:halt:/sbin:/sbin/halt 
-mail:x:8:12:mail:/var/spool/mail: 
-news:x:9:13:news:/var/spool/news: 
-uucp:x:10:14:uucp:/var/spool/uucp: 
-operator:x:11:0:operator:/root: 
-games:x:12:100:games:/usr/games: 
-gopher:x:13:30:gopher:/usr/lib/gopher-data: 
-ftp:x:14:50:FTP User:/home/ftp: 
-nobody:x:99:99:Nobody:/: 
-xfs:x:43:43:X Font Server:/etc/X11/fs:/bin/false 
-named:x:25:25:Named:/var/named:/bin/false 
-gdm:x:42:42::/home/gdm:/bin/bash 
-postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash 
-shrek:x:500:500:Shrek Ogre:/home/shrek:/bin/bash 
-fiona:x:501:501:Fiona Ogre :/home/fiona:/bin/bash 
-</code> 
-El archivo ''/etc/passwd'' puede entrar en 5 bloques enteros de 4 lineas 
  • awk.1681262311.txt.gz
  • Última modificación: 2023/04/12 01:18
  • por peron