Tengo un archivo que incluye detalles sobre las máquinas virtuales que se ejecutan en un hipervisor. Ejecutamos algún comando y redirigimos la salida a un archivo. Y los datos están disponibles en el siguiente formato.
Virtual Machine : OL6U5
ID : 0004fb00000600003da8ce6948c441bb
Status : Running
Memory : 65536
Uptime : 17835 Minutes
Server : MyOVS1.vmorld.com
Pool : HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Virtual Machine : OL6U6
ID : 0004fb00000600003da8ce6948c441bc
Status : Running
Memory : 65536
Uptime : 17565 Minutes
Server : MyOVS2.vmorld.com
Pool : NON-HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Virtual Machine : OL6U7
ID : 0004fb00000600003da8ce6948c441bd
Status : Running
Memory : 65536
Uptime : 17835 Minutes
Server : MyOVS1.vmorld.com
Pool : HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Esta salida difiere de hipervisor a hipervisor ya que en algunos hipervisores tenemos más de 50 vms en ejecución. El archivo anterior es solo un ejemplo del hipervisor en el que solo tenemos 3 máquinas virtuales en ejecución y, por lo tanto, se espera que el archivo redirigido contenga información sobre varias (N número de máquinas virtuales)
Necesitamos obtener estos detalles en el siguiente formato usando awk / sed o con un script de shell
Virtual_Machine ID Status Memory Uptime Server Pool HA VCPU Type OS
OL6U5 0004fb00000600003da8ce6948c441bb Running 65536 17835 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
OL6U6 0004fb00000600003da8ce6948c441bc Running 65536 17565 MyOVS2.vmworld.com NON-HA-POOL false 16 Xen PVM Oracle Linux 6
OL6U5 0004fb00000600003da8ce6948c441bd Running 65536 17835 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
text-processing
sed
awk
IgniteLX
fuente
fuente
Respuestas:
Si recorrer el archivo dos veces no es un problema (grande) (almacenará solo una línea en la memoria):
Lo cual, para un recuento general de campos sería (que podría tener muchos recorridos del archivo):
Pero para una transposición realmente general, esto funcionará:
Y para hacerlo bonito (usando la pestaña
\t
como separador de campo):El código anterior para una transposición general almacenará toda la matriz en la memoria.
Eso podría ser un problema para archivos realmente grandes.
Actualización para nuevo texto.
Para procesar el nuevo texto publicado en la pregunta, me parece que dos pasos de awk son la mejor respuesta. Una pasada, tan corta como existan campos, imprimirá los títulos de los campos de encabezado. El próximo pase awk imprimirá solo el campo 2. En ambos casos, agregué una forma de eliminar los espacios iniciales y finales (para un mejor formato).
El entorno
{ ... } | column -t -s "$(printf '%b' '\t')"
es formatear toda la tabla de una manera bonita.Tenga en cuenta que
"$(printf '%b' '\t')"
podría reemplazarse por$'\t'
ksh, bash o zsh.fuente
Si tiene la
rs
utilidad (remodelar) disponible, puede hacer lo siguiente:Esto proporciona el formato de salida exactamente como se especifica en la pregunta, incluso hasta los anchos de columna dinámicos.
-T
Transpone los datos de entrada.-z
dimensiona las columnas adecuadamente desde el máximo en cada columna-c:
usa dos puntos como separador de campo de entradaEsto funciona para tablas de tamaño arbitrario, por ejemplo:
rs
está disponible de forma predeterminada en OS X (y probablemente en otras máquinas BSD). Se puede instalar en Ubuntu (y la familia Debian) con:fuente
EDITAR: Extensible a cualquier número de filas de salida, en un simple
for
bucle de una línea :Respuesta original:
Puede hacer esto como una línea usando la
bash
sustitución de procesos:La
-s
opciónpaste
hace que maneje cada archivo de uno en uno. El:
delimitador establecidopaste
está "atrapado" por la-s
opción alcolumn
final, para mejorar el formato haciendo que los campos se alineen.Los
cut
comandos en las dos sustituciones de proceso extraen el primer campo y el segundo campo, respectivamente.Si hay líneas en blanco en la entrada o no, no importa, ya
column -t -s:
que limpiará la salida independientemente. (Había líneas en blanco en la entrada original especificada en la pregunta, pero desde entonces se han eliminado. El comando anterior funciona independientemente de las líneas en blanco).Entrada: contenido del archivo llamado "entrada" en el comando anterior:
Salida:
fuente
Usando awk, guarde la clave y el valor e imprímalos al final.
El solo corre
awk -f ./script.awk ./input.txt
fuente
fuente
Con
gnu datamash
ycolumn
desdeutil-linux
:Esto funciona con más de dos columnas, pero supone que no hay líneas vacías en su archivo de entrada; con líneas vacías en el medio (como en su muestra de entrada inicial) obtendría un error como:
para evitar tener que apretarlos antes de procesar con
datamash
:De lo contrario, en este caso particular (solo dos columnas), con
zsh
y lo mismocolumn
:(${(f)"$(<infile)"})
lee las líneas en una matriz;${(j;:;)list[@]%:*}
une (con:
) el primer campo de cada elemento y${(j;:;)list[@]#*:}
une (nuevamente con:
) el segundo campo de cada elemento; ambos están impresos, por ejemplo, la salida esque luego se canaliza a
column -t -s:
fuente
cat <(head -n 11 virtual.txt | cut -d: -f1) <(sed 's/.*: //' virtual.txt) | xargs -d '\n' -n 11 | column -t
El número de líneas por máquina virtual está codificado en este caso: 11. Será mejor contarlo de antemano y almacenarlo en la variable, luego usar esta variable en el código.
Explicación
cat <(command 1) <(command 2)
- la<()
construcción hace que lacommand
salida aparezca como un archivo temporal. Por lo tanto,cat
concatena dos archivos y los canaliza aún más.head -n 11 virtual.txt | cut -d: -f1
nos da futuros encabezados de columna. La entrada de una máquina virtual son las primeras once líneas, elhead
comando se usa para obtenerla. Elcut
divide esta entrada a dos columnas e imprimir la única primera.sed 's/.*: //' virtual.txt
nos da valores de columna futuros.sed
elimina todo el texto innecesario y deja solo valores.xargs -d '\n' -n 11
. Cada elemento de entrada termina en nueva línea. Este comando obtiene elementos y los imprime en 11 por línea.column -t
- es necesario para pantallas bonitas de impresión. Muestra nuestras líneas en forma de tabla. De lo contrario, cada línea tendrá un ancho diferente.Salida
fuente
Use
datamash
y sutranspose
opción para intercambiar filas y columnas en un archivo.De forma predeterminada, la transposición verifica que la entrada tiene el mismo número de campos en cada línea y, de lo contrario, falla con un error y puede deshabilitar su modo estricto para permitir valores perdidos por
--no-strict
También puede usar
--filler
para establecer el valor de relleno de campo faltante:derivado de
datamash manual
fuente
si sus datos están en archivos separados en un directorio, puede usar:
Es posible que necesite masajear el número de caracteres
\t
(tabulación) en laprintf
línea si sus valores variables son de diferentes longitudes.fuente