Notas del comando Awk

awk 'BEGIN { commands } PATTERN { commands } END { commands }'
     begin块               body块                 end块
  1. begin/end distingue entre mayúsculas y minúsculas y las mayúsculas son válidas.
  2. Los espacios son opcionales.
  3. Las variables integradas deben escribirse con mayúscula.

Proceso de ejecución:
1) Ejecute primero el bloque de inicio.
Equivalente a la inicialización del bucle.
2) Para cada registro de entrada, ejecute el bloque del cuerpo.
Equivale a ejecutar el cuerpo del bucle.
Si está procesando texto de varias líneas, el valor predeterminado es dividir el registro con un carácter de nueva línea, es decir, recorrer cada línea para su procesamiento.
3) Procesamiento predeterminado para cada registro (cada línea de texto):
separe los campos de cada línea con un delimitador (el valor predeterminado es un espacio), y asigne valores a $1, $2... ($0 representa la línea completa) a Procese
cada campo según sea necesario, salida, etc.
4) Después de que termine el bucle, ejecute el bloque final.

patrón patrón:
1) /expresión regular/: /some string/
2) expresión relacional: $2>10 NR%2==0
3) expresión de coincidencia de patrón: ~ ~!
4) intervalo de rango:
'NR==1, NR==10'1-10 líneas

$ cat /tmp/test.log 
2023-05-18 05:08:56.965846   460  4936 I SOMEIP  : 2023-05-18 05:08:56.871641 [info] [TID:571]  repetitionsBaseDelay_ = 100
2023-05-18 05:08:56.965863   460  4936 I SOMEIP  : 2023-05-18 05:08:56.871645 [info] [TID:571]  repetitionsMax_ = 3
2023-05-18 05:08:30.896556  1538  1538 I SettingsIFImpl: line 1
2023-05-18 05:08:30.896556  1538  1538 I SettingsIFImpl: line 2

# 包含SOMEIP的行
$ awk '/SOMEIP/' /tmp/test.log
2023-05-18 05:08:56.965846   460  4936 I SOMEIP  : 2023-05-18 05:08:56.871641 [info] [TID:571]  repetitionsBaseDelay_ = 100
2023-05-18 05:08:56.965863   460  4936 I SOMEIP  : 2023-05-18 05:08:56.871645 [info] [TID:571]  repetitionsMax_ = 3

# 不包含SOMEIP的行
$ awk '!/SOMEIP/' /tmp/test.log
2023-05-18 05:08:30.896556  1538  1538 I SettingsIFImpl: line 1
2023-05-18 05:08:30.896556  1538  1538 I SettingsIFImpl: line 2

# 把字段$6匹配模式的行,打印每行中$6后续内容
$ awk 'BEGIN{ ORS=" " } $6~/SOMEIP/{ for(i=8; i<=NF; i++) { print $i } print "\n" }' /tmp/test.log
2023-05-18 05:08:56.871641 [info] [TID:571]  repetitionsBaseDelay_ = 100 
 2023-05-18 05:08:56.871645 [info] [TID:571]  repetitionsMax_ = 3 
 2023-05-18 05:08:56.871641 [info] [TID:571]  repetitionsBaseDelay_ = 100 
 2023-05-18 05:08:56.871645 [info] [TID:571]  repetitionsMax_ = 3 

variables integradas

FILENAME: 当前文件名
NR: 表示所有处理文件已处理的输入记录个数
FNR: 文件的当前记录数
NF: 表示数据文件中数据字段的个数,可以通过$NF获取最后一个数据字段
ARGC: 命令行参数个数
ARGV: 命令行参数数组
$0: 这个变量包含执行过程中当前行的文本内容。
$n: 一行记录的第n个字段,例如$1, $2

FS:输入字段分隔符
OFS:输出字段分隔符
RS:输入记录分割符
ORS:输出字段分隔符
FIELDWIDTHS:定义数据字段的宽度
$ awk '{print FILENAME, NF, $0}' /tmp/test.log 
/tmp/test.log 8 2023-05-18 05:08:30.896556  1538  1538 I SettingsIFImpl: line 1
/tmp/test.log 8 2023-05-18 05:08:30.896556  1538  1538 I SettingsIFImpl: line 2

$ awk '{print FILENAME "line>>" NR, $0}' /tmp/test.log 
/tmp/test.logline>>1 2023-05-18 05:08:30.896556  1538  1538 I SettingsIFImpl: line 1
/tmp/test.logline>>2 2023-05-18 05:08:30.896556  1538  1538 I SettingsIFImpl: line 2

bloque de cuerpo:

/pattern/ {
    
     commands }

1) Ejecute los comandos para los registros que coincidan con el patrón de expresión regular.
2) Puede haber múltiples patrones coincidentes, por ejemplo:
(1) Cuando el patrón1 coincide, se ejecuta el comando1. Si el patrón 2 coincide, se ejecutará el comando 2.
(2) La función de siguiente es omitir la siguiente coincidencia de patrón y los comandos (similar a la relación if/else); si no hay un comando siguiente, se evaluará cada coincidencia de patrón.

/patten1/ {
    
    commands1; next} /pattern2/ {
    
    commands2}

3) Si se omite {comandos}, la impresión $0 se ejecuta de forma predeterminada. Solo se realiza el filtrado de /patrón/coincidencia.
(1) Para cadenas simples, degenere en grep.
(2) Use variables y expresiones integradas para realizar búsquedas complejas (filtrado), como filtrar filas pares.

$ awk '/Max/' /tmp/test.log 
$ awk 'NR%2==0' /tmp/test.log

4) La función de impresión puede redirigir la salida a un archivo o tubería en los comandos

awk 'NR%2==0 { print $1 > "/tmp/part.log" }' /tmp/test.log

Cada bloque de comando:
1) Se pueden escribir varias declaraciones. Un comando por línea, sin punto y coma al final. Los comandos múltiples también se pueden separar con punto y coma.
2) Soporte if-else, for, while y otras estructuras de control.
3) Datos de soporte, el índice puede ser un número o una cadena, lo que equivale a un mapa.
4) Funciones personalizables
function find_min(num1, num2) { if (num1 < num2) return num1 return num2 }
5) Funciones integradas:
(1) Funciones matemáticas: sin, cos, log, sqrt, int, rand
(2) Funciones de cadenas: gsub, sub, substr, index, length, match, split, tolower , toupper, sprintf, strtonum
sub(reg, str [, target])
a) Registro de coincidencia de cadena, reemplazado por str.
b) destino es la cadena de destino de reemplazo, el valor predeterminado es 0, se puede especificar como una tabla o campo 0 y se puede especificar como una tabla o campo0 , que se puede especificar como una tabla o un campo n.
c) gsub es el mismo que el prototipo de sub, reemplazando todas las cadenas que coinciden con reg, y sub solo reemplaza la primera aparición.
gensub(reg, str, h [, target])
a) h puede especificar cuántas ocurrencias de reg reemplazar, o "g/G" para reemplazar todas.
b) En str, "\n" se puede usar para referirse a la posición donde aparece reg.
imprimir
(3) Funciones de tiempo: mktime, strftime, systime
(4) Funciones de operación de bits: and, or, xor, compl, lshift, rshift
(5) Otras funciones: close, flush, exit, delete, getline, next, nextfile, sistema de retorno

# sub,gsub例子
# sub
$ cat /tmp/test.log 
2023-05-18 05:08:56.965846   460  4936 I SOMEIP  : 2023-05-18 05:08:56.871641 [info] [TID:571] client_timer_18215_1 repetitionsBaseDelay_ = 100
2023-05-18 05:08:56.965863   460  4936 I SOMEIP  : 2023-05-18 05:08:56.871645 [info] [TID:571] client_timer_18215_1 repetitionsMax_ = 3

#sub函数只替换第一次出现的字符串
$ awk '{ sub(/2023-05-18/, "1234-56-78"); print $0 }' /tmp/test.log 
1234-56-78 05:08:56.965846   460  4936 I SOMEIP  : 2023-05-18 05:08:56.871641 [info] [TID:571] client_timer_18215_1 repetitionsBaseDelay_ = 100
1234-56-78 05:08:56.965863   460  4936 I SOMEIP  : 2023-05-18 05:08:56.871645 [info] [TID:571] client_timer_18215_1 repetitionsMax_ = 3

#gsub函数替换一行中所有匹配的字符串
$ awk '{ gsub(/2023-05-18/, "1234-56-78"); print $0 }' /tmp/test.log 
1234-56-78 05:08:56.965846   460  4936 I SOMEIP  : 1234-56-78 05:08:56.871641 [info] [TID:571] client_timer_18215_1 repetitionsBaseDelay_ = 100
1234-56-78 05:08:56.965863   460  4936 I SOMEIP  : 1234-56-78 05:08:56.871645 [info] [TID:571] client_timer_18215_1 repetitionsMax_ = 3

# gsub删除收尾空格
$ awk '{gsub(/^ +| +$/,"")} {print "=" $0 "="}' onefile.txt

Dividir registros con múltiples delimitadores:

$ cat test.log
2023-05-18 05:08:56.965846   460  4936 I SOMEIP

# 用空格、.、:多个分隔符来拆分记录,默认只用空格分隔符
$ awk -F "[ .:]" '{print $1,$2,$3,$4,$5}' test.log 
2023-05-18 05 08 56 965846

# FS和-F参数等效
$ awk 'BEGIN{FS="[ .:]"} {print $1,$2,$3,$4,$5}' test.log 
2023-05-18 05 08 56 965846

Las variables personalizadas
1) son más útiles para los scripts, pero no muy útiles en la línea de comandos.
2) En la línea de comando, las variables personalizadas se escriben después de las instrucciones del script. Las instrucciones del script están al lado de awk.

$ awk '{ print name"="age }' name=tom age=12 /tmp/test.log 
tom=12
tom=12

Array:
1) Array asociativo, tipo mapa.
2) No es necesario definir primero
3) El bucle for...in puede estar fuera de servicio, mientras que el bucle for (i=1...) está en orden

$ awk '
BEGIN {
str="this is a string"; 
len=split(str, array, " "); 
print length(array), len; 
for (i in array) 
	print i": "array[i]; 
}'

4 4
1: this
2: is
3: a
4: string

$ awk 
'BEGIN {
str="this is a string"; 
len=split(str, array, " "); 
print length(array), len; 
for (i=1; i<=len; i++) 
	print i": "array[i]; 
}'
4 4
1: this
2: is
3: a
4: string

$ awk 
'BEGIN{ 
arr["one"]=1; 
arr["two"]=2; 
arr["three"]=3; 

for (item in arr) 
	print item"->"arr[item] 
}'
three->3
two->2
one->1

Control de procesos:

$ cat /tmp/file.txt 
line 1
line 2
line 3
line 4
line 5
line 6

# if
$ awk '{ 
if (NR % 2 == 0) 
{
	print $0
} 
else if (NR %3 == 0) 
{
	print $0
} 
}' /tmp/file.txt 

line 2
line 3
line 4
line 6

# while 循环
$ awk 'BEGIN{ 
count=3; 
while (count>0) 
{
	print count; 
	count--;
} 
}' /tmp/file.txt 
3
2
1

# for循环
$ awk 'BEGIN{ 
for(count=3; count>0; count--) 
{
	print count;
} 
}' /tmp/file.txt 
3
2
1

comandos de control:

break,退出while/for循环
continue,继续下一次循环
next,继续系一条记录,把body块作为循环体,next类似continue,跳到下一条记录。
exit, 在body块中exit,结束body块循环,执行END;在END中exit,退出程序。包body块作为循环体,exit类似break。

Ejemplo de cálculo numérico:


$ cat /tmp/num.txt
1
2
3
4
5
# 计算均值
$ awk 'BEGIN{ sum=0; } { sum+=$1; } END{ print sum/NR }' /tmp/num.txt 
3

$ cat /tmp/num.txt
1 2 3 4 5
11 22 33 44 55
10 20 30 40 50
# 计算均值
$ awk '{ sum=0; for(i=1; i<=NF; i++) sum+=$i; print sum/NF }' /tmp/num.txt 
3
33
30


Awk puede personalizar funciones, que no se utilizan por el momento, y no se grabarán.

Supongo que te gusta

Origin blog.csdn.net/yinminsumeng/article/details/130618023
Recomendado
Clasificación