uso de combate awk

¡Trabajar juntos para crear y crecer juntos! Este es el día 34 de mi participación en el "Nuevo plan diario de Nuggets · Desafío de actualización de agosto", haga clic para ver los detalles del evento

Hay una noticia muy interesante recientemente. El experto en informática Brian Kernighan, de 80 años, también conocido como K en K & R, sigue contribuyendo con código a awk y agregando soporte para Unicode. Consulte los antecedentes detallados y la entrevista original .

Me avergüenza decirlo, he usado awk muchas veces, intencionalmente o no, en los últimos años, pero siempre me olvido de usarlo, me olvido de verificarlo nuevamente y nunca lo he solucionado sistemáticamente. Solo aprovecha esta oportunidad para revisar el posicionamiento y uso común de awk, una herramienta clásica, similar a grep, sed, sort, curl, etc.

Hoy revisaremos awk primero .

awk

En los sistemas similares a Unix, awk es una herramienta integrada, que generalmente se usa para el filtrado de datos, el procesamiento de texto y, de manera similar a sed y grep, es esencialmente un filtro de filtro.

La herramienta awk define su propio lenguaje de secuencias de comandos para procesar datos de texto a través de una serie de acciones. Si está interesado, puede consultar la Guía del usuario de GNU Awk para obtener la documentación completa .

awk no requiere compilación y permite a los usuarios usar variables, funciones numéricas, funciones de cadena y operadores lógicos. Con su ayuda, los desarrolladores pueden escribir scripts muy sofisticados pero efectivos, definir un conjunto de patrones de búsqueda de texto y encontrar la acción que se ejecutará después.

Muchos estudiantes están más interesados ​​en saber por qué dicha herramienta se llama awk. De hecho, su significado es el nombre de los tres fundadores de la montaña:

Ahoy, Weinberger, Kernighan

Análisis de habilidad

¿Qué podemos hacer con awk?

  1. Escanee el contenido del archivo línea por línea;
  2. Divida la línea de entrada de datos en varios campos;
  3. Coincidencia de patrones en datos de entrada;
  4. 针对匹配的行做一些操作(action)。

基本语法

awk 命令的格式如下:

awk options 'selection _criteria {action }' input-file > output-file
复制代码

事实上如果大家忘记了,直接在自己的 mac 或者 linux 上运行 awk,就会出现帮助提示:

$ awk

usage: awk [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]
复制代码

这里提供了两个选项

-f program-file : Reads the AWK program source from the file 
                  program-file, instead of from the 
                  first command line argument.
-F fs            : Use fs for the input field separator
复制代码

实战用法

假定我们有一个 employee.txt 文件,内容如下:

ajay manager account 45000
sunil clerk account 25000
varun manager sales 50000
amit manager account 47000
tarun peon sales 15000
deepak clerk sales 23000
sunil peon sales 13000
satvik director purchase 80000 
复制代码

awk 默认会打印指定文件里所有行:

$ awk '{print}' employee.txt
复制代码

此时因为没有提供需要匹配的模式,所以这个 print action 对于所有行都适用,并且 print action 如果没有参数就会默认打印一行里的所有内容。

所以运行上面命令,会打印出来原本的文本内容

ajay manager account 45000
sunil clerk account 25000
varun manager sales 50000
amit manager account 47000
tarun peon sales 15000
deepak clerk sales 23000
sunil peon sales 13000
satvik director purchase 80000 
复制代码

ok,如果只是这样就太鸡肋了,我们的 employee.txt 的特征还是很明显的,可以分析出来文本的第一列是员工姓名,第二列看起来是职位。

现在我们希望过滤出来所有 manager,可以这样运行:

$ awk '/manager/ {print}' employee.txt 
复制代码

此时会打印

ajay manager account 45000
varun manager sales 50000
amit manager account 47000 
复制代码

前面是匹配的模式,后面 {} 中的则是具体的 action。

除了模式能够调整外,action 也是可以调整的,如果我们不希望用 print 默认的行为,现在想将一行 split 成多个 field 怎么办?

awk 默认会根据空格来 split 每一行数据,并将每个 field 存储在 norte en estas variables. Por ejemplo, una línea tiene 4 个单词,那么分隔后的结果将会被存储在 n 这些变量中。比如一行有 4 个单词,那么分隔后的结果将会被存储在 1, 2 , 2, 3, 4 这四个变量中。注意, 4 这四个变量中。注意, 0 代表了整个行。

所以,如果我们想基于 employee.txt 打印出来各个员工的名字和薪资(最后一列),可以这样做:

$ awk '{print $1,$4}' employee.txt 
复制代码

此时会打印出来:

ajay 45000
sunil 25000
varun 50000
amit 47000
tarun 15000
deepak 23000
sunil 13000
satvik 80000 
复制代码

第一列,第四列,完美符合预期。

除了上面我们提到的 $n 这些变量外,awk 还提供了一些内置的变量供开发者使用:

NR

NR command keeps a current count of the number of input records. Remember that records are usually lines. Awk command performs the pattern/action statements once for each record in a file.

NR 即 Number of Record, 记录了当前已经计数过的 record(行)数量。比如下面的命令:

$ awk '{print NR,$0}' employee.txt 
复制代码

此时会你会看到前面加上了行号:

1 ajay manager account 45000
2 sunil clerk account 25000
3 varun manager sales 50000
4 amit manager account 47000
5 tarun peon sales 15000
6 deepak clerk sales 23000
7 sunil peon sales 13000
8 satvik director purchase 80000 
复制代码

这里我们也可以加一些分隔符,比如打印编号 + 第一列,用- 来隔开,就可以这样:

$ awk '{print NR "-" $1 }' employee.txt
复制代码

得到的输出如下:

1-ajay
2-sunil
3-varun
4-amit
5-tarun
6-deepak
7-sunil
8-satvik
复制代码

当然,我们还可以活用 NR 来输出指定行:

$ awk 'NR==3, NR==6 {print NR,$0}' employee.txt 
复制代码

这样的命令代表了我们要打印 3 - 6 行这个区间内的行,输出如下:

3 varun manager sales 50000
4 amit manager account 47000
5 tarun peon sales 15000
6 deepak clerk sales 23000 
复制代码

有时候我们想打印出来一个文件的行号,就可以取最后一行的 NR,此时所有行都计数过了,所以 NR 等价于总行数:

$ awk 'END { print NR }' employee.txt 
复制代码

这里运行结果为 8,符合预期。

NF

NF command keeps a count of the number of fields within the current input record.

NF 即 Number of Field,记录了当前输入的 record 列的数量,我们可以用 $NF 来代表最后一列。

$ awk '{print $1,$NF}' employee.txt 
复制代码

运行之后,我们看到此时打印的是第一列和最后一列

ajay 45000
sunil 25000
varun 50000
amit 47000
tarun 15000
deepak 23000
sunil 13000
satvik 80000 
复制代码

NR + NF

现在我们有了 NR 和 NF,可以联系起来做什么呢?

比如此时我们希望找到空行的行号,假设有一些行就是没数据,是空的,怎么打印?

为了测试,我在第五行加了个空行,变成了这样:

ajay manager account 45000
sunil clerk account 25000
varun manager sales 50000
amit manager account 47000

tarun peon sales 15000
deepak clerk sales 23000
sunil peon sales 13000
satvik director purchase 80000
复制代码

其实很简单,空行的 NF 一定为 0,打印行号可以用 NR,所以我们可以这样:

$ awk 'NF==0 {print NR}' employee.txt
复制代码

运行后结果是 5,符合预期。

length

awk 提供了 length 函数计算字符串长度,比如我们希望找到所有比 80 个字符还长的行,可以这样:

awk 'length($0) > 80' employee.txt
复制代码

可能有些同学不理解,这里为啥不加 print 呀?

De hecho, puede probarlo e imprimirlo sin agregarlo, porque la acción predeterminada es imprimir.

Usar una sentencia if como patrón

A veces queremos hacer coincidir en función del valor de una determinada columna. Supongamos que queremos encontrar la fila donde el valor de la tercera columna es igual a las ventas, lo que se puede hacer así:

$ awk '{ if($3 == "sales") print $0;}' employee.txt
复制代码

Imprime el resultado después de ejecutar:

varun manager sales 50000
tarun peon sales 15000
deepak clerk sales 23000
sunil peon sales 13000
复制代码

Cálculos numéricos

A veces no necesariamente tenemos un archivo fuente, sino que queremos construir directamente las condiciones en el bucle for. Puedes consultar este ejemplo:

$ awk 'BEGIN { for(i=1;i<=6;i++) print "square of", i, "is",i*i; }' 
复制代码

Aquí encontrará que no proporcionamos el parámetro del archivo fuente, sino que proporcionamos un bucle for directamente en el patrón e imprimimos los siguientes valores para el intervalo i = 1 a 6. Resultado de salida:

square of 1 is 1
square of 2 is 4
square of 3 is 9
square of 4 is 16
square of 5 is 25
square of 6 is 36
复制代码

No hay una acción predeterminada para las reglas BEGIN y END, debemos proporcionar una impresión de acción explícita.

resumen

Hoy revisamos los conceptos básicos de awk, combinados con algunos casos prácticos para comprender el uso común de awk, estos no son todos, awk proporciona un conjunto completo de lenguajes para el procesamiento de texto.

Lo que enumeramos aquí es solo la punta del iceberg. Si está interesado, consulte la Guía del usuario para un estudio en profundidad, que será de gran beneficio para el procesamiento de texto.

¡Gracias por leer!

Supongo que te gusta

Origin juejin.im/post/7136957973674328072
Recomendado
Clasificación