Programación Linux Bash Shell (7): Intercepción y procesamiento de cadenas (cut, printf, awk, sed)

Programación Linux Bash Shell (7): Intercepción y procesamiento de cadenas (cortar, imprimirf, awk, sed, ordenar) con ejemplos

  En la sección anterior , aprendimos sobre las funciones básicas y el uso de expresiones regulares. En esta sección, estudiaremos los comandos de interceptación de cadenas, salida formateada y procesamiento de cadenas.

Shell7

comando de corte

El comando de corte es un comando de intercepción de cadena en Bash, que puede cortar algunas columnas de un archivo con un separador uniforme (arbitrario) en una línea.

cut [options] <filename>
Opciones Descripción
-si Seleccione solo los bytes especificados
-C Seleccione solo los caracteres especificados
-F Seleccione solo estos dominios especificados
-re Use el delimitador especificado (el valor predeterminado es un tabcarácter de tabulación) (usado en modo -f) El delimitador debe ser un solo carácter
-s No mostrar líneas que no contengan delimitadores (se utilizan en el modo -f), que se muestran de forma predeterminada
  • Entre ellos, los primeros tres elementos son opciones obligatorias y mutuamente excluyentes (elija una de tres) , lo que -dsignifica separados por bytes, -csignifica separados por caracteres, -fsignifica separados por delimitadores (forman un dominio que puede contener múltiples caracteres o espacios vacíos), generalmente La separación de dominios es más común
  • Si una línea no contiene un delimitador, el comando cambiará la línea y generará la línea completa, a menos que se especifique la -sopción
  • -fEl parámetro de número de campo es obligatorio después de la opción, que puede ser varias líneas (separadas por comas) o un conjunto (ab)
  • -dLa opción especifica el delimitador, que debe estar entre comillas simples y puede ser un espacio
  • El comando de corte puede tener limitaciones, pero la sintaxis es más simple y fácil de implementar.

Ejemplo:

#截取用户配置文件passwd文件中,所有用户名以及对应UID
cut -s -d ":" -f 1,3 passwd
root:0
daemon:1
bin:2
#文件内容仅截取部分

#截取passwd文件中,所有组的附加用户
cut -d ":" -f 1,4 gshadow
root:
daemon:
bin:
cdrom:zheng
floppy:zheng
#文件内容仅截取部分

#截取所有非root非系统用户
zheng@Kali:~/temp$ grep "/bin/bash" /etc/passwd | cut -d ":" -f 1
root
postgres #这个用户是某些服务需要的管理用户,同样具有可bash登录特性,需要额外排除
zheng
test

comando printf

printf es un comando de salida formateado de bash, printf también se puede usar como salida estándar en el comando awk, que se usa para generar cadenas \ contenido digital que permite un formato definido. La sintaxis es similar al comando de salida con formato printf en lenguaje C

printf '<输出类型><输出格式>' <输出内容>
#输出类型字符串中同样可以加入字符串用于说明,输出内容可以专注于变量等
  • El tipo de salida y el formato de salida deben incluirse entre comillas simples
  • El contenido de salida es generalmente números, variables, etc., separados por espacios.
Tipo de salida Descripción
% ns Cadena de salida, n es un número, lo que significa que se emiten varios caracteres (n se puede omitir)
% ni Generar un entero, n es un número, lo que significa generar varios números (n se puede omitir)
% m.nf Números de punto flotante de salida, myn son números, que indican el número de dígitos de salida (incluidos enteros y decimales) y el número de posiciones decimales% 4.3f significa generar un número con un entero y cuatro posiciones decimales

Ejemplo:

#将输出内容识别为字符串类型输出
printf '%s' 1 2 as 12 3
12as123 #此行后没有换行符,直接开始下一行

printf '%s\n' 1 2 as 12 #按字符串输出,并且每个输出内容后增加换行符
1
2
as
12

#按字符串输出,并且三个一组增加空格和换行
printf '%s %s %s\n' 1 2 as 12 4 3
1 2 as
12 4 3

#printf的输出格式中也可以增加一些文字内容,后面的内容专注于变量输出
printf 'Hello, %s\n' "Zheng"
Hello, Zheng

comando awk

  Comparado con el comando cut, el comando awk es más poderoso. Puede interceptar cadenas de caracteres separadas por espacios de diferentes longitudes y realizar funciones como programación de funciones, juicio condicional y control de flujo en las cadenas de caracteres. Pero al mismo tiempo, su estructura de lenguaje es más complicada que cortada, similar a un lenguaje de programación.

awk 'pattern1{action1}pattern2{action2}...' <filename>
  • patrón: condición, generalmente una expresión relacional (por ejemplo, x> 1), puede estar vacía, el valor predeterminado no pasa el juicio condicional, todas las acciones se ejecutan

  • acción: Acción, que puede formatearse salida (awk admite printf, print) comandos o declaraciones de control de flujo

  • El comando awk aún procesa la entrada por línea

  • printfprintLa diferencia entre el comando y el comando es que el último agrega automáticamente una nueva línea después del final de la salida, mientras que el primero no

  • Después de que el comando awk lee la cadena de línea, separa el contenido por el separador (si hay varios espacios, también se puede separar), y se $nexpresa usando , n es un número, lo que $0significa todo el contenido de la línea, $1significa la primera columna, $2significa la segunda columna Y así

  • El comando awk proporciona una variable prefabricada FScomo separador. El comando es correcto taby spaceválido por defecto , pero si se trata de otros símbolos, es necesario preestablecerlo, por lo general utilizando BEGINpreestablecimientos de condición.

  • La condición BEGIN, como patternuso, declara la BEGINcondición que actionse ejecutará antes de que el comando awk lea la primera línea de la cadena, y puede ejecutar comandos que deben ejecutarse una vez por adelantado.

  • Condición END, el uso es el mismo que BEGIN, se ejecuta una vez después de leer todo el contenido

    Por ejemplo: es necesario definir el delimitador antes de interceptar la variable passwd,

    awk 'BEGIN{FS=":";print "Begin"}END{print "End"}{print $1 "\t" $3}' /etc/passwd
    Begin
    root    0
    daemon  1
    bin     2
    sys     3
    End
    #可以看到,分界符在一开始(未读取数据前)就被定义,正常截取并输出了第一行
    
    #但如果没有使用 BEGIN 条件,而是将分界符定义与格式化输出放在一起
    awk '{FS=":";print $1 "\t" $3}' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    daemon  1
    bin     2
    sys     3
    #在定义分界符之前,第一行数据就已经被读入,无法对第一行数据重新截取,导致整行输出
    

Ejemplo:

#下面的awk命令示例没有条件仅有动作
df -h | awk '{printf $1 "\t" $5 "\t" $6 "\n"}' 
文件系统        已用%   挂载点
udev    0%      /dev
tmpfs   1%      /run
/dev/sda5       38%     /
tmpfs   0%      /dev/shm
tmpfs   0%      /run/lock
tmpfs   0%      /sys/fs/cgroup
/dev/sda1       28%     /boot
tmpfs   1%      /run/user/1000

El siguiente ejemplo proporciona una función para verificar la ocupación del sistema de archivos montado en el directorio raíz y alarma cuando es demasiado alto

En primer lugar, ahora use el carácter de barra vertical en la línea de comando para interceptar gradualmente el contenido de ocupación requerido

#原理:使用df命令查看文件系统占用信息
df

#筛选出需要的根目录挂载信息,每一行以挂载位置结尾,根目录仅有"\",可以作为判断依据
df | grep "/$"
#正则表达式内容见上一节

#接下来得到一行信息,该信息以space分隔,需要使用awk截取命令,获得第五列信息
df | grep "/$" | awk '{print $5}' 

#接下来,需要将百分号去掉,仅需要一个数字
df | grep "/$" | awk '{print $5}' | cut -d "%" -f 1
#由于占用率可能是一位或两位,稳妥方法使用域截取

#命令结果是需要的正确信息
df | grep "/$" | awk '{print $5}' | cut -d "%" -f 1
38

Después de obtener la información de ocupación que necesitamos, escríbala en el script para comparar el tamaño,

#以下是脚本df中内容

#!/bin/bash

#Author:Zheng

declare -i a
a=$(df | grep "/$" | awk '{print $5}' | cut -d "%" -f 1)
if [ $a -lt 80 ]; then #条件判断语句在后面内容中会讲到
        echo "Storage space normal" #如果a小于80
else
        echo "Warning:Not enough storage space" #如果a大于80
fi
echo -e "root storage used $a%"

Obtenga el efecto:

0zheng@Kali:~/Shell$ ./df.sh 
Storage space normal
root storage used 38%

Hay muchas otras funciones del comando awk (como control de procesos, programación funcional, etc.). Debido a limitaciones de espacio, no lo discutiremos con mayor profundidad. Si está interesado, puede consultar otra información

comando sed

sed es un editor de flujo ligero incluido en casi todas las plataformas UNIX (puede aceptar flujos de datos de tuberías). Sed puede seleccionar, reemplazar, eliminar y agregar datos

sed [选项] {
    
    脚本} [文件]
Opciones Descripción
-norte Salida silenciosa (todos los datos se enviarán a la pantalla de forma predeterminada), solo las líneas procesadas por el comando sed se enviarán a la pantalla
-yo Utilice el resultado modificado de sed para modificar directamente el archivo que lee los datos en lugar de mostrarlo en la pantalla
acción Descripción
una Agregar, agregue cualquier línea después de la línea actual, excepto por la última línea, debe agregar "\" al final de cada línea para indicar que los datos no han terminado
C Reemplazo de línea, reemplace la línea de datos original con la cadena de caracteres después de c. Cuando reemplace varias líneas, agregue "\" al final de cada línea excepto la última línea para indicar que los datos no terminaron
yo Insertar, insertar cualquier fila antes de la fila actual, agregar "" para varias filas
re Eliminar la fila especificada
pags Imprimir, generar la línea especificada
s Reemplazo de cadena, reemplace otra cadena con una cadena, el formato es "rango de línea s / cadena antigua / cadena nueva / g" (similar a vim)
  • En general, se recomienda habilitar la -nopción al generar la salida , de lo contrario, el comando volverá a generar todas las líneas leídas
  • Agregue, inserte y reemplace líneas si modifica varias líneas, inserte la primera línea de contenido después de la acción con un espacio y luego use una barra invertida para ingresar y continuar insertando el siguiente contenido

Ejemplo:

#以下是示例文件b中内容
ID      Name    gender  Mark
1       LiHua   M       86
2       HZ      M       90
3       Cooper  M       89

#下面开始测试
#测试1:追加动作a(多行)
sed '4a End\
> Hello World' b
ID      Name    gender  Mark
1       LiHua   M       86
2       HZ      M       90
3       Cooper  M       89
End
Hello World
#测试2:行替换命令
sed '4c Cooper Absent\
> End' b
ID      Name    gender  Mark
1       LiHua   M       86
2       HZ      M       90
Cooper Absent
End
#测试3:插入命令
sed '1i Test Results' b
Test Results
ID      Name    gender  Mark
1       LiHua   M       86
2       HZ      M       90
3       Cooper  M       89
#测试4:删除行命令
sed '2,4d' b #注意,逗号表示行范围的始末,非单独行
ID      Name    gender  Mark
#测试4:输出指定的行
sed -n '3p' b
2       HZ      M       90
#测试5:字符串替换
sed '4s/M/F/g' b
ID      Name    gender  Mark
1       LiHua   M       86
2       HZ      M       90
3       Cooper  F       89

orden de clasificación

El comando sort clasifica las líneas de cadena en un orden determinado

sort [options] [filename]
Opciones Descripción
-F Ignorar caso
-norte Ordenar por tipo numérico (tipo de cadena predeterminado)
-r Orden inverso
-t Según el delimitador especificado (pestaña de pestaña predeterminada)
-kn, m Ordene de acuerdo con el rango de campo especificado, comenzando desde el campo n y terminando con m (predeterminado al final de la línea)
  • El campo especificado de la opción -k se refiere a una columna y se puede especificar un solo campo (-kn)

Ejemplo:

#以下是passwd原文件前几行内容
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync

#按用户名字符串排序
sort /etc/passwd
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
avahi:x:124:129:Avahi mDNS daemon,,,:/run/avahi-daemon:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin

#按组ID排序(需要指定分隔符,且排序依据为数字型)
sort -t ":" -k 4 -n /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin

índice

La siguiente sección, Linux Bash Shell Programming (8): Juicio condicional y ejemplos Comenzaremos a aprender el juicio condicional y las declaraciones de control de flujo en Bash

La sección anterior, Linux Bash Shell Programming (6): ejemplos de aplicación de metacaracteres básicos en expresiones regulares

Supongo que te gusta

Origin blog.csdn.net/Zheng__Huang/article/details/108015558
Recomendado
Clasificación