J'ai un fichier qui contient des détails sur les machines virtuelles exécutées dans un hyperviseur. Nous exécutons une commande et redirige la sortie vers un fichier. Et les données sont disponibles dans le format ci-dessous.
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
Cette sortie diffère d'hyperviseur à hyperviseur car sur certains hyperviseurs, nous avons 50 + vms en cours d'exécution. Le fichier ci-dessus est juste un exemple de l'hyperviseur où nous n'avons que 3 machines virtuelles en cours d'exécution et donc le fichier redirigé devrait contenir des informations sur plusieurs (nombre N de machines virtuelles)
Nous devons obtenir ces détails dans le format ci-dessous en utilisant awk / sed ou avec un script 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
la source
la source
Réponses:
Si parcourir le fichier deux fois n'est pas un (gros) problème (ne stockera qu'une seule ligne en mémoire):
Ce qui, pour un nombre général de champs serait (qui pourrait avoir de nombreuses promenades dans le fichier):
Mais pour une transposition vraiment générale, cela fonctionnera:
Et pour le rendre joli (en utilisant tab
\t
comme séparateur de champ):Le code ci-dessus pour une transposition générale stockera la matrice entière en mémoire.
Cela pourrait être un problème pour les très gros fichiers.
Mise à jour pour le nouveau texte.
Pour traiter le nouveau texte affiché dans la question, il me semble que deux passes de awk sont la meilleure réponse. Une passe, aussi courte que les champs existent, imprimera les titres des champs d'en-tête. La prochaine passe awk n'imprimera que le champ 2. Dans les deux cas, j'ai ajouté un moyen de supprimer les espaces de début et de fin (pour un meilleur formatage).
L'environnement
{ ... } | column -t -s "$(printf '%b' '\t')"
est de formater la table entière d'une manière jolie.Veuillez noter que le
"$(printf '%b' '\t')"
pourrait être remplacé par$'\t'
dans ksh, bash ou zsh.la source
Si vous disposez de l'
rs
utilitaire (remodeler) , vous pouvez effectuer les opérations suivantes:Cela donne le format de sortie exactement comme spécifié dans la question, même jusqu'à la largeur des colonnes dynamiques.
-T
Transpose les données d'entrée-z
dimensionne les colonnes de manière appropriée à partir du maximum dans chaque colonne-c:
utilise deux points comme séparateur de champ de saisieCela fonctionne pour les tables de taille arbitraire, par exemple:
rs
est disponible par défaut sur OS X (et probablement sur d'autres machines BSD). Il peut être installé sur Ubuntu (et la famille Debian) avec:la source
EDIT: extensible à n'importe quel nombre de lignes de sortie, dans une simple
for
boucle à une ligne :Réponse originale:
Vous pouvez le faire en une ligne en utilisant la
bash
substitution de processus:L'
-s
option permettant depaste
gérer chaque fichier un par un. Le:
délimiteur défini danspaste
est "capturé" par l'-s
optioncolumn
à la fin, pour améliorer le format en alignant les champs.Les
cut
commandes des deux substitutions de processus extraient respectivement le premier champ et le deuxième champ.Qu'il y ait ou non des lignes vides dans l'entrée n'a pas d'importance, car
column -t -s:
cela nettoiera la sortie malgré tout. (Il y avait des lignes vides dans l'entrée d'origine spécifiée dans la question, mais elles ont depuis été supprimées. La commande ci-dessus fonctionne indépendamment des lignes vides.)Input - contenu du fichier nommé "input" dans la commande ci-dessus:
Production:
la source
En utilisant awk, stockez la clé et la valeur et imprimez-les à la fin.
La course juste
awk -f ./script.awk ./input.txt
la source
la source
Avec
gnu datamash
etcolumn
deutil-linux
:Cela fonctionne avec plus de deux colonnes mais suppose qu'il n'y a pas de lignes vides dans votre fichier d'entrée; avec des lignes vides entre les deux (comme dans votre échantillon d'entrée initial), vous obtiendrez une erreur comme:
donc pour éviter de devoir les presser avant de les traiter avec
datamash
:Sinon, dans ce cas particulier (seulement deux colonnes), avec
zsh
et pareilcolumn
:(${(f)"$(<infile)"})
lit les lignes d'un tableau;${(j;:;)list[@]%:*}
joint (avec:
) le premier champ de chaque élément et${(j;:;)list[@]#*:}
joint (à nouveau avec:
) le deuxième champ de chaque élément; ils sont tous deux imprimés, par exemple la sortie estqui est ensuite canalisé vers
column -t -s:
la source
cat <(head -n 11 virtual.txt | cut -d: -f1) <(sed 's/.*: //' virtual.txt) | xargs -d '\n' -n 11 | column -t
Le nombre de lignes par machine virtuelle est codé en dur dans ce cas - 11. Mieux vaut le compter à l'avance et le stocker dans la variable, puis utiliser cette variable dans le code.
Explication
cat <(command 1) <(command 2)
- la<()
construction faitcommand
apparaître la sortie comme un fichier temporaire. Par conséquent,cat
concatène deux fichiers et le redirige.head -n 11 virtual.txt | cut -d: -f1
, nous donne les en- têtes de colonnes futures. La seule entrée de la machine virtuelle est onze premières lignes, lahead
commande est utilisée pour l'obtenir. Lecut
divise cette entrée en deux colonnes et imprime la seule première.sed 's/.*: //' virtual.txt
- nous donne les valeurs futures des colonnes.sed
supprime tout le texte inutile et ne laisse que des valeurs.xargs -d '\n' -n 11
. Chaque élément d'entrée est terminé par une nouvelle ligne. Cette commande récupère les éléments et les imprime par 11 par ligne.column -t
- est nécessaire pour les jolis tirages. Il affiche nos lignes sous forme de tableau. Sinon, chaque ligne aura une largeur différente.Production
la source
Utilisez
datamash
et sontranspose
option pour permuter des lignes et des colonnes dans un fichier.Par défaut, transpose vérifie que l'entrée a le même nombre de champs dans chaque ligne, et échoue avec une erreur sinon et vous pouvez désactiver son mode strict pour autoriser les valeurs manquantes en
--no-strict
Vous pouvez également utiliser
--filler
pour définir la valeur de remplissage de champ manquant:dérivé de
datamash manual
la source
si vos données sont dans des fichiers séparés dans un répertoire, vous pouvez utiliser:
vous devrez peut-être masser le nombre de
\t
(tabulation) caractères sur laprintf
ligne si vos valeurs variables sont de longueurs différentes.la source