
Tengo una secuencia de comandos que verifica el sistema de archivos montado con la entrada que figura en fstab, el problema al que me enfrento aquí es mantener la salida alineada.
A continuación se muestra el resultado del script:
/ is mounted OK
/boot is mounted OK
/was8 is mounted OK
/was8/slogs is mounted OK
/was8/cluster is mounted OK
/was8/working is mounted OK
/was8/app is mounted OK
/was8/tools is mounted OK
/was8/plugin is mounted OK
/was8/coreproduct is mounted OK
...
Quiero mantener estas líneas alineadas para que se vean así:
/ is mounted OK
/boot is mounted OK
/was8 is mounted OK
/was8/slogs is mounted OK
/was8/cluster is mounted OK
/was8/working is mounted OK
/was8/app is mounted OK
/was8/tools is mounted OK
/was8/plugin is mounted OK
/was8/coreproduct is mounted OK
...
Probé column y xargs y no pude obtener el resultado deseado. Puede alguien ayudarme con esto.
Respuesta1
En general, cuando estás imprimiendo, puedes establecer el ancho en la cadena de formato en printf
. %-20s
imprimiría una cadena en un campo de 20 caracteres (*) de ancho, a menos que se desborde. %-20.20s
lo convertiría en 20 caracteres y eliminaría cualquier parte desbordante.
(* Aunque, por ejemplo, Bash printf
en realidad cuentabytes. La diferencia se puede ver con caracteres como ä
en UTF-8.)
Entonces, por ejemplo
printf "%-40s %s\n" "$mountpoint is mounted" "$status"
haría que la primera parte (al menos) tuviera 40 caracteres de ancho:
/was8/coreproduct is mounted OK
...
O, si necesita posprocesar una entrada como esa, puede usar Perl o awk:
perl -pe 's/(.*) +(\S+)$/ sprintf "%-40s %s", $1, $2 /e' < file
awk '{s=$NF; sub(/ *[^ ]+ *$/, "", $0); printf "%-40s %s\n", $0, s}' < file
Básicamente, ambos separan la última cadena que no es un espacio en blanco y luego imprimen las dos partes con la primera en un campo de ancho fijo.
O, si no le importa mantener la separación entre los campos exactamente como estaban, una solución más sencilla comentada por @JJoaosería:
awk '{s=$NF; NF-- ; printf "%-40s %s\n", $0, s}' < file
Eso produce el siguiente resultado. Tenga en cuenta que los dos espacios en blanco anteriores is mounted
se contraen a uno. Esto sucede ya que awk
reconstruye el conjunto $0
cuando NF
se modifica alguno de los campos.
/was8/coreproduct is mounted OK
Respuesta2
Sólo un poco de confusión sobre Perl:
perl -ne 'printf "%-40s %s", /(.*) (.*)/s'
Respuesta3
Una forma es introducir una pestaña antes del código de estado, por ejemplo:
<input rev | sed 's/ /\t/' | rev | column -s $'\t' -t
Producción:
/ is mounted OK
/boot is mounted OK
/was8 is mounted OK
/was8/slogs is mounted OK
/was8/cluster is mounted OK
/was8/working is mounted OK
/was8/app is mounted OK
/was8/tools is mounted OK
/was8/plugin is mounted OK
/was8/coreproduct is mounted OK
/was8/ihs is mounted OK
/was8/backup is mounted OK
/was8/ihs/logs is mounted OK
/was8/wsdm is mounted OK
/was8/ws is mounted OK
/was8/ihs/logs/analysis is mounted OK
Respuesta4
Esto también se puede hacer muy fácilmente con la utilidad de columna. La clave es incluir algún tipo de marcador diferenciador entre tus 'columnas'. Por ejemplo, si el espacio es el marcador diferenciador, entonces column -s ' ' -o ' ' -t
se alineará perfectamente en los espacios.
Utilizo esto con frecuencia e incluso he creado algunas macros vim agradables que lo utilizan para alinear el código. La sintaxis general que desea es:
column -s <Separator String> -o <Separator String in Output> -t
Esta es una generalización de la respuesta basada en pestañas, pero no requiere necesariamente la inserción de pestañas.