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
\tcomo 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
rsutilidad (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.
-TTranspone los datos de entrada.-zdimensiona 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:
rsestá 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
forbucle de una línea :Respuesta original:
Puede hacer esto como una línea usando la
bashsustitución de procesos:La
-sopciónpastehace que maneje cada archivo de uno en uno. El:delimitador establecidopasteestá "atrapado" por la-sopción alcolumnfinal, para mejorar el formato haciendo que los campos se alineen.Los
cutcomandos 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.txtfuente
fuente
Con
gnu datamashycolumndesdeutil-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
zshy 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 -tEl 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 lacommandsalida aparezca como un archivo temporal. Por lo tanto,catconcatena dos archivos y los canaliza aún más.head -n 11 virtual.txt | cut -d: -f1nos da futuros encabezados de columna. La entrada de una máquina virtual son las primeras once líneas, elheadcomando se usa para obtenerla. Elcutdivide esta entrada a dos columnas e imprimir la única primera.sed 's/.*: //' virtual.txtnos da valores de columna futuros.sedelimina 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
datamashy sutransposeopció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-strictTambién puede usar
--fillerpara establecer el valor de relleno de campo faltante:derivado de
datamash manualfuente
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 laprintflínea si sus valores variables son de diferentes longitudes.fuente