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.
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 tab cará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
-d
significa separados por bytes,-c
significa separados por caracteres,-f
significa 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
-s
opción -f
El 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)-d
La 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 |
- El formato de salida del comando printf es
echo
exactamente el mismo que el del comando. No lo repetiré aquí. Consulte Programación del shell Bash de Linux (1): descripción general del shell e implementación de Hello World
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
-
printf
print
La 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
$n
expresa usando , n es un número, lo que$0
significa todo el contenido de la línea,$1
significa la primera columna,$2
significa la segunda columna Y así -
El comando awk proporciona una variable prefabricada
FS
como separador. El comando es correctotab
yspace
válido por defecto , pero si se trata de otros símbolos, es necesario preestablecerlo, por lo general utilizandoBEGIN
preestablecimientos de condición. -
La condición BEGIN, como
pattern
uso, declara laBEGIN
condición queaction
se 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
-n
opció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