GNU/Linux >> Tutoriales Linux >  >> Linux

¿Dividir la salida del comando por columnas usando Bash?

Una manera fácil es agregar un pase de tr para exprimir cualquier separador de campo repetido:

$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4

Tenga en cuenta que el tr -s ' ' La opción no eliminará ningún espacio inicial único. Si su columna está alineada a la derecha (como con ps pid)...

$ ps h -o pid,user -C ssh,sshd | tr -s " "
 1543 root
19645 root
19731 root

Luego, cortar dará como resultado una línea en blanco para algunos de esos campos si es la primera columna:

$ <previous command> | cut -d ' ' -f1

19645
19731

A menos que lo preceda con un espacio, obviamente

$ <command> | sed -e "s/.*/ &/" | tr -s " "

Ahora, para este caso particular de números pid (no nombres), hay una función llamada pgrep :

$ pgrep ssh


Funciones de shell

Sin embargo, en general, todavía es posible usar funciones de shell de manera concisa, porque hay algo interesante sobre el read comando:

$ <command> | while read a b; do echo $a; done

El primer parámetro para leer, a , selecciona la primera columna, y si hay más, todo lo demás se pondrá en b . Como resultado, nunca necesitará más variables que el número de su columna +1 .

Entonces,

while read a b c d; do echo $c; done

luego generará la tercera columna. Como se indica en mi comentario...

Se ejecutará una lectura canalizada en un entorno que no pasa variables al script de llamada.

out=$(ps whatever | { read a b c d; echo $c; })

arr=($(ps whatever | { read a b c d; echo $c $b; }))
echo ${arr[1]}     # will output 'b'`


La solución de matriz

Entonces terminamos con la respuesta de @frayser, que es usar la variable de shell IFS, que por defecto es un espacio, para dividir la cadena en una matriz. Sin embargo, solo funciona en Bash. Dash y Ash no lo apoyan. Me ha costado mucho dividir una cadena en componentes en una cosa Busybox. Es bastante fácil obtener un solo componente (por ejemplo, usando awk) y luego repetirlo para cada parámetro que necesite. Pero luego termina llamando repetidamente a awk en la misma línea, o usando repetidamente un bloque de lectura con eco en la misma línea. Lo cual no es eficiente ni bonito. Entonces terminas dividiendo usando ${name%% *} y así. Te hace anhelar algunas habilidades de Python porque, de hecho, los scripts de shell ya no son muy divertidos si la mitad o más de las funciones a las que estás acostumbrado desaparecen. Pero puede suponer que ni siquiera python estaría instalado en dicho sistema, y ​​no lo estaba;-).


Creo que la forma más sencilla es usar awk . Ejemplo:

$ echo "11383 pts/1    00:00:00 bash" | awk '{ print $4; }'
bash

Linux
  1. Usando el comando de suspensión de Linux en Bash Scripts

  2. Cómo dividir iso o archivo usando el comando 'dividir' en Linux

  3. Usando la salida de comandos anteriores en bash

  4. Falla la redirección de la salida del comando a una variable en bash

  5. ¿Redirigir toda la salida al archivo usando Bash en Linux?

Bash:escribir en archivo

bash heredoc

Comando de fuente Bash

Comando Bash printf

Mostrar la salida del comando Ping en formato gráfico usando Gping

Usando el comando Dirname de Linux en Bash Scripts