Linux: secuencias de comandos de shell avanzadas (sed / gawk)

Tabla de contenido

Comando sed avanzado

Mantenga el espacio y el espacio del patrón

Aplicación de ejemplo de artículo avanzado de sed

Comando avanzado de gawk


 

#Este artículo es una nota de estudio

 

Comando sed avanzado

Comando 1> n: pasar a la siguiente línea

El comando n minúscula le dirá al editor sed que se mueva a la siguiente línea del flujo de datos para procesar

 

1.1 Principio del comando n

El comando n es simplemente leer la siguiente línea por adelantado, cubriendo la línea anterior del espacio modelo (no se elimina, por lo que todavía se imprime en la salida estándar). Si el comando no se ejecuta correctamente (no se omite: las condiciones del front-end no coinciden), entonces abandone. Cualquier comando y vuelva a ejecutar sed para el contenido recién leído.

ejemplo:

Saque líneas pares del archivo aaa

1

2

3

4

5

6

7

8

9

10

cat aaa 

This is 1    

This is 2    

This is 3    

This is 4    

This is 5    

     

sed -n 'n;p' aaa         //-n表示隐藏默认输出内容    

This is 2    

This is 4


Nota: Lea esto es 1, ejecute el comando n, el espacio de modo es Esto es 2, ejecute p, imprima el contenido del espacio de modo Esto es 2, luego lea Esto es 3, ejecute el comando n, el espacio de modo es Esto es 4. Ejecuta p, imprime el contenido del espacio de modo Esto es 4, luego lee Esto es 5, ejecuta el comando n, porque no hay más, así que sal y abandona el comando p.

Por lo tanto, las líneas pares se imprimen al final.

 

Comando 2> N: fusionar líneas de texto

La N mayúscula agregará la siguiente línea de texto al texto existente en el espacio del patrón, de modo que las dos líneas de texto se fusionen en el mismo espacio del patrón y las líneas de texto aún estén separadas por saltos de línea. Si desea encontrar texto que pueda estar disperso en dos líneas en un archivo, esta es una función muy útil.

 

2.1 Principio del comando N:

El comando N es simplemente para agregar la siguiente línea al espacio del patrón y, al mismo tiempo, tratar las dos líneas como una sola línea, pero todavía hay un carácter de nueva línea entre las dos líneas. Si el comando no se ejecuta correctamente (no se omite: las condiciones del front-end no coinciden), entonces Renuncie a cualquier comando después de eso y ejecute sed nuevamente para el contenido recién leído.

ejemplo:

Leer líneas impares del archivo aaa

1

2

3

4

5

6

7

8

9

10

11

cat aaa   

This is 1   

This is 2   

This is 3   

This is 4   

This is 5   

                                                     

sed -n '$!N;P' aaa            

This is 1   

This is 3   

This is 5

En el comentario, 1 representa Esto es 1 2 representa Esto es 2 y así sucesivamente

Nota: La condición de lectura 1, $! Está satisfecha (no la última línea), ejecuta el comando N, obtén 1 \ n2, ejecuta P, imprime 1, lee 3, la condición $! Está satisfecha (no la última línea), ejecuta el comando N, obtén De 3 \ n4, ejecute P, imprima 3, lea 5, la condición $! No se cumple, omita N, ejecute P, imprima 5

2.2 Ejemplo de configuración

例1
$ cat data2.txt
this is the header line.
this is the first data line.
this is the second data line.
this is the last line.

$ sed '/first/{N;s/\n/ /}' data2.txt
this is the header line.
this is the first data line. this is the second data line.
this is the last line.

例2
$ cat data3.txt
on Tuesday,the linux system
administrator's group meeting will be held.
all system administrators should attend.
thank you for your attendance.

$ sed 'N;s/system.administrator/desktop user/' data3.txt
on Tuesday,the linux desktop user's group meeting will be held.
all desktop users should attend.
thank you for your attendance.

 

3> Solo elimine el comando en la línea anterior, comando D

Cuando hay varias líneas coincidentes, el comando D solo eliminará la primera línea en el espacio del patrón

 

3.1 Principio de funcionamiento del comando D

El comando D borra el contenido desde el comienzo del espacio del modo actual a \ n (no se transmite a la salida estándar), abandona los comandos posteriores, pero vuelve a ejecutar sed en el espacio del modo restante.

Ejemplo de comando D

Leer la última línea del archivo aaa

1

2

3

4

5

6

7

8

9

cat aaa   

This is 1   

This is 2   

This is 3   

This is 4   

This is 5   

                                                

sed 'N;D' aaa           

This is 5

Nota: Leer 1, ejecutar N, obtener 1 \ n2, ejecutar D, obtener 2, ejecutar N, obtener 2 \ n3, ejecutar D, obtener 3, y así sucesivamente, obtener 5, ejecutar N, condición No se puede salir porque no hay un parámetro -n, por lo que la salida 5

 

3.2 Ejemplo de configuración


$ cat data5.txt

this is the header line.
this is a data line.

this is the last line.

例1:
$ sed '/^$/{N;/header/D}' data5.txt
this is the header line.
this is a data line.

this is the last line.

例2:打印最后两行
sed '$!N;$!D' data5.txt

this is the last line.

 

4> Solo imprime la línea anterior, comando P

Cuando hay varias líneas coincidentes, el comando P solo imprimirá la primera línea en el espacio del patrón

$ sed -n 'N;/system\nadministrator/P' data3.txt
on Tuesday,the linux system

5> Excluir comando (!)

例1
$ cat data2.txt
this is the header line.
this is the first data line.
this is the second data line.
this is the last line.

$ sed -n '/headeer/!p' data2.txt
this is the first data line.
this is the second data line.
this is the last line.

6> Rama. Se usa para cambiar el flujo de datos

Formato: [dirección] b [: etiqueta]

El parámetro de dirección determina qué filas de datos activarán el comando de rama, y ​​el parámetro de etiqueta define la ubicación a la que saltar.

例1
$ cat data2.txt
this is the header line.
this is the first data line.
this is the second data line.
this is the last line.
$ sed '{2,3b;s/this is /is this/;s/line./test?/}' data2.txt
is this the header test?
this is the first data line.
this is the second data line.
is this the last test?

例2
$ sed '{/first/b jump1;s/this is the/no jump on/
>:jump1
>s/this is the/jump here on/}' data2.txt

no jump on header line
jump here on first data line
no jump on second data line
no jump on last line

例3
$ sed -n '{
> :start
> s/,//1p
> b start
> }'

 

7> Comando de prueba (prueba). Se utiliza para cambiar el flujo de ejecución del script del editor sed, que es equivalente a "o" en el operador lógico.

例1
$ cat data2.txt
this is the header line.
this is the first data line.
this is the second data line.
this is the last line.
$ sed '{
>s/first/matched/
>t
>s/this is the/no match on/
}' data2.txt
no match on header line
this is the matched data line
no match on second data line
no match on last line

例2
$ echo "this,is,a,test,to,remove,commas."|sed -n '{
>:start
>s/,/ /1p
>b start
}'
#当无需替换时,测试命令不会跳转而是继续执行剩下的脚本

 

8> Modo alternativo / referencia inversa (&)

El símbolo & se usa para representar el patrón coincidente en el comando reemplazar. Cuando desee hacer coincidir parte de la cadena, puede usar paréntesis para definir el subpatrón en el patrón y usar \ 1, \ 2, etc. para representar el subpatrón que llama.

例1
$ echo 'the cat sleeps in his hat'|sed 's/.at/"&"/g'
the "cat" sleeps in his "hat"

例2
$ echo 'the system administrator manual'|sed '
>s/\(system\) administrator/\1 user/'
the system user manual

例3
$ echo '1234567'|sed '{
>:start
>s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
>t start
>}'
1,234,567

 

Mantenga el espacio y el espacio del patrón

Espacio de modo: es el área de búfer donde el editor sed almacena el texto a procesar. Sed leerá una línea de texto a la vez, la colocará en el espacio del patrón y ejecutará comandos de edición.

Mantener espacio: un búfer para guardar temporalmente algunas líneas.

Hay cinco comandos para manipular el espacio de espera:

h Copie el espacio del patrón en el espacio de espera (se sobrescribirá)
H Agregar espacio de patrón para mantener el espacio
gramo Copie el espacio de espera al espacio del patrón
GRAMO Agregar espacio de espera al espacio de patrón
X Intercambia el contenido del espacio del patrón y mantén el espacio

 

例1
$ cat data2.txt
this is the header line.
this is the first data line.
this is the second data line.
this is the last line.
$ sed -n '{1!G;h;$p}' data2.txt
this is the last line.
this is the second data line.
this is the first data line.
this is the header line.

 

 

Aplicación de ejemplo de artículo avanzado de sed

Texto de ejemplo:

cat data2.txt
  esta es la línea de encabezado.
  esta es la primera línea de datos.
  esta es la segunda línea de datos.
  esta es la última línea.


实例:
例1:加倍行间距,每行后面加一行空白行;
$ sed 'G' data2.txt
this is the header line.

this is the first data line.

this is the second data line.

this is the last line.

$ sed '$!G' data2.txt      #每行后面加一空白行,最后一行不加
this is the header line.

this is the first data line.

this is the second data line.

this is the last line.
$

 

例2:给文件中的行编号;
$ sed '=' data2.txt | sed 'N;s/\n'/ /'
1 this is the header line.
2 this is the first data line.
3 this is the second data line.
4 this is the last line.
#如果有空白行的话,需要注意先去除空白行
例3:打印末尾10行
$ sed '{
> :start
> $q;N;11,$D
> b start
> }' data7.txt
例4:删除空白行
$ sed '/./,/^$/!d' data8.txt     #删除连续空白行;
$ sed '/./,$!d' data9.txt        #删除开头n行空白行;
$ sed '{                         #删除末尾空白行;
> :start
> /^\n*$/{$d;N;b start}
> }'

 

Comando avanzado de gawk

1> Variables integradas

ANCHOS DE CAMPO Una serie de números separados por espacios que definen el ancho exacto de cada campo de datos.
FS 输入字段分隔符,默认是空格符
RS 输入记录分隔符,每行是一条记录,默认是换行符
OFS 输出字段分隔符,默认是空格符
ORS 输出记录分隔符,每行是一条记录,默认是换行符

 

数据变量:

NF 字段总数
NR 已处理的行数
ENVIRON

关联数组组成的shell环境变量值,格式如下

print ENVIRON["HOME"]

   
例1:将逗号分隔符替换为“-”,并输出前三项
$ cat data1
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35

$ gawk 'BEGIN{FS=",";OFS="-"} {print $1,$2,$3}' data1
data11-data12-data13
data21-data22-data23
data31-data32-data33

 

例2:将每行当作一个字段,把空白行当作记录分隔符
$ cat data2
riley mullen
123 main street
chicago,il 60601
555-1234

frank williams
456 oak street
indianapolis ,in 46201
5559876

haley snell
4231 elm street
detroit,mi 48201
555-4938

$ gawk 'BEGIN{FS="\n";RS=""} {print $1,$4}' data2
riley mullen 555-1234
frank williams 555-9876
haley snell 555-4938
例3:按固定宽度分隔字段
$ cat data1b
1005.3247596.37
115-2.349194.00
05810.1298100.1

$ gawk 'BEGIN{FIELDWIDTHS="3 5 2 5"}{print $1,$2,$3,$4}' data1b
100 5.324 75 96.37
115 -2.34 91 94.00
058 10.12 98 100.1
例4:在脚本中使用变量赋值
$ gawk '
> BEGIN{
> testing="this is a test"
> print testing
> testing=46
> print testing
> }'

$ this a testing
$ 45
遍历关联数组
$ gawk 'BEGIN{
> var[a]=1
> var[g]=2
> var[u]=3
> for (test in var)
> {
> print "index:",test," "- Value:",var[test]
> }
> }'

index: u  - Value: 3
index: a  - Value: 1
index: g  - Value: 2

删除数组元素值:
delete array[index]
匹配限定
$ gawk -F: '$1 ~ /rich/{print $1,$NF}' data1
rich /bin/bash
#这个例子会在第一个数据字段中查找文本rich。如果在记录中找到了这个模式,它会打印
该记录的第一个和最后一个数据字段值;
数学表达式应用
$ gawk -F: '$4 == 0 {print $1}' /etc/passwd
root
sync
shutdown
halt
operator
结构化命令,if语句
if (condition)
statement1
也可以将它放在一行上,像这样:
if (condition) statement1

$ gawk '{if ($1 > 20) print $1}' data4
$ gawk '{
> if ($1 > 20)
> {
> x=$1 * 2
> print x
> }
> }' data4


$ gawk '{
> if ($1 > 20)
> {
> x = $1 * 2
> print x
> } else
> {
> x = $1 / 2
> print x
> }}' data4

可以在单行上使用else子句,但必须在if语句部分之后使用分号。
if (condition) statement1; else statement2


结构化命令,while语句
while (condition)
{
statements
}

$ gawk '{
> total = 0
> i = 1
> while (i < 4)
> {
> total += $i
> i++
> }
> avg = total / 3
> print "Average:",avg
> }' data5


$ gawk '{
> total = 0
> i = 1
> while (i < 4)
> {
> total += $i
> if (i == 2)
> break
> i++
> }
> avg = total / 2
> print "The average of the first two data elements is:",avg
> }' data5

结构化命令,do-while语句类似于while语句,但会在检查条件语句之前执行命令。下面是do-while语
句的格式。
do
{
statements
} while (condition)
这种格式保证了语句会在条件被求值之前至少执行一次。当需要在求值条件前执行语句时,
这个特性非常方便。
$ gawk '{
> total = 0
> i = 1
> do
> {
> total += $i
> i++
> } while (total < 150)
> print total }' data5



for语句是许多编程语言执行循环的常见方法。gawk编程语言支持C风格的for循环。
for( variable assignment; condition; iteration process)
将多个功能合并到一个语句有助于简化循环。
$ gawk '{
> total = 0
> for (i = 1; i < 4; i++)
> {
> total += $i
> }
> avg = total / 3
> print "Average:",avg
> }' data5
格式化输出,printf,和c语言用法一样
c 将一个数作为ASCII字符显示
d 显示一个整数值
i 显示一个整数值(跟d一样)
e 用科学计数法显示一个数
f 显示一个浮点值
g 用科学计数法或浮点数显示(选择较短的格式)
o 显示一个八进制值
s 显示一个文本字符串
x 显示一个十六进制值
X 显示一个十六进制值,但用大写字母A~F


注意,你需要在printf命令的末尾手动添加换行符来生成新行。没添加的话,printf命令
会继续在同一行打印后续输出。

printf默认输出是右对齐,可通过“-”来控制成左对齐:
$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%-16s %s\n", $1, $4}' data2
Riley Mullen (312)555-1234
Frank Williams (317)555-9876
Haley Snell (313)555-4938
$

处理浮点数:
$ gawk '{
> total = 0
> for (i = 1; i < 4; i++)
> {
> total += $i
> }
> avg = total / 3
> printf "Average: %5.1f\n",avg
> }' data5
Average: 128.3
Average: 137.7
Average: 176.7
$
#打印test.txt的第3行至第5行
awk 'NR==3,NR==5 {print}' test.txt
#打印test.txt的第3行至第5行的第一列与最后一列
awk 'NR==3,NR==5 {print $1,$NF}' test.txt

#打印test.txt中长度大于80的行号
awk 'length($0)>80 {print NR}' test.txt

#计算test.txt中第一列的总和
cat test.txt|awk '{sum+=$1}END{print sum}'

#添加自定义字符
ifconfig eth0|grep 'Bcast'|awk '{print "ip_" $2}'


#格式化输出
awk -F: '{printf "% -12s % -6s % -8s\n",$1,$2,$NF}' /etc/passwd

 

注:本章内容为读书笔记,摘自《Linux命令行与shell脚本编程大全》第3版。

Supongo que te gusta

Origin blog.csdn.net/qq_35229961/article/details/90693541
Recomendado
Clasificación