J'ai un fichier avec les lignes comme ci-dessous.
title1:A1
title2:A2
title3:A3
title4:A4
title5:A5
title1:B1
title2:B2
title3:B3
title4:B4
title5:B5
title1:C1
title2:C2
title3:C3
title4:C4
title5:C5
title1:D1
title2:D2
title3:D3
title4:D4
title5:D5
Comment puis-je atteindre cet objectif?
title1 title2 title3 title4
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4
D1 D2 D3 D4
Réponses:
Jetez un oeil à la datamash GNU qui peut être utilisée comme
datamash transpose
. Une future version prendra également en charge la tabulation croisée (tableaux croisés dynamiques)la source
En dehors de rouler une solution personnalisée pour transposer des lignes avec des colonnes à partir d'une ligne de commande, le seul outil que j'ai jamais vu qui puisse le faire est un outil appelé ironiquement
transpose
.Installation
Malheureusement, il ne se trouve dans aucun dépôt, vous devrez donc le télécharger et le compiler. C'est assez simple car il n'a pas de bibliothèques supplémentaires dont il dépend. Cela peut être accompli comme suit:
Usage
Il peut facilement gérer des fichiers texte simples. Par exemple:
Peut être transposé à l'aide de cette commande:
Cette commande consiste
transpose
à transposer (-t
) et le séparateur de champ à utiliser est un espace (--fsep " "
).Votre exemple
Étant donné que vos exemples de données sont dans un format légèrement plus complexe, ils doivent être traités en 2 phases. Nous devons d'abord le traduire dans un format
transpose
compatible.L'exécution de cette commande mettra les données dans un format plus convivial horizontalement:
Il nous suffit maintenant de supprimer les occurrences secondaires du titre1, du titre2, etc.:
C'est maintenant dans un format qui
transpose
peut gérer. La commande suivante fera toute la transposition:la source
Vous pouvez alors utiliser
awk
pour traiter les donnéespaste
etcolumn
les formater.Ici, je suppose que ce
title1
n'est qu'un exemple dans votre message, et que les données ne contiennent:
que comme séparateur entre en-tête + données.n
signifie le nombre de colonnes à imprimer (doit correspondre aux tiretspaste
).Si vous voulez le rendre plus flexible et plus facile à entretenir, vous pouvez l'écrire sous forme de script. Voici un exemple d'utilisation de wrapper bash pour
awk
et canalisé verscolumn
. De cette façon, vous pouvez également faire plus de vérification de données, par exemple en vous assurant que les en-têtes sont corrects sur toutes les lignes, etc.Utilisé généralement comme:
Si les en-têtes sont toujours plus courts que les données, vous pouvez également enregistrer les largeurs d'en-tête, puis
printf
avec%-*s
et sautercolumn
tous ensemble.la source
Voici un moyen rapide de mettre le fichier au format souhaité:
Si vous voulez les en-têtes de colonne:
Fonctionnement de la 2e commande
impression de la bannière mettre un retour après la bannière impression des lignes de donnéesla source
Utilitaire de datamash GNU
Tiré de ce site, https://www.gnu.org/software/datamash/ et http://www.thelinuxrain.com/articles/transposing-rows-and-columns-3-methods
la source
Il existe probablement une façon plus succincte de formuler cela, mais cela semble produire l'effet général:
Les
sed
invocations multiples ne se sentent pas bien (et je suis presque sûr que sed peut également faire la traduction de la nouvelle ligne), donc ce n'est probablement pas la façon la plus simple de le faire. En outre, cela supprime les en-têtes potentiels, mais vous pouvez les générer manuellement une fois que les lignes / champs sont correctement formatés.Une meilleure réponse distillerait probablement cet effet en utilisant simplement
sed
ouawk
en faisant ceci de sorte que vous n'ayez qu'une chose à faire à la fois. Mais je suis fatigué donc c'est ce que j'ai pu mettre en place.la source
paste
est probablement votre meilleur pari. Vous pouvez extraire les bits pertinents aveccut
,grep
etawk
comme ceci:Si la 5ème colonne doit être supprimée, ajoutez
awk 'NR%5'
comme ceci:Colonne maintenant avec
paste
:Production:
la source
Pour juste la partie transposée, j'ai eu un problème similaire récemment et j'ai utilisé:
Ajustez le fmt au besoin. Pour chaque ligne d'entrée, il concatène chaque champ sur un élément de tableau. Notez que la concaténation de chaînes awk est implicite: elle se produit lorsque vous écrivez deux choses sans aucun opérateur.
Exemple d'E / S:
production:
la source
La chose la plus simple que vous puissiez faire est d'utiliser
cut
pour couper les champs et ensuite utilisertr
si vous transposez des lignes en colonnes en remplaçant le caractère de nouvelle ligne par un caractère de tabulation: http://www.gnu.org/software/coreutils/manual/ coreutils.html # tr-invocationla source
cut
renvoie une erreur.