J'ai deux fichiers texte. Le premier a un contenu:
Languages
Recursively enumerable
Regular
tandis que le second a du contenu:
Minimal automaton
Turing machine
Finite
Je veux les combiner dans un fichier par colonne. Alors j'ai essayé paste 1 2
et sa sortie est:
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Cependant, j'aimerais bien que les colonnes soient bien alignées, comme
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Je me demandais s'il serait possible d'y parvenir sans manipulation manuelle?
Ajoutée:
Voici un autre exemple, où la méthode de Bruce la cloue presque, à l'exception d'un léger désalignement sur lequel je me demande pourquoi?
$ cat 1
Chomsky hierarchy
Type-0
—
$ cat 2
Grammars
Unrestricted
$ paste 1 2 | pr -t -e20
Chomsky hierarchy Grammars
Type-0 Unrestricted
— (no common name)
pr
etexpand
...columns
évite ce problème.➀ unicode may render oddly
but the column count is ok
définitivement ne s'appliquent pas àwc-paste-pr
etwc-paste-pr
ils affichez les différences de nombre de colonnes .. Les autres sont ok.pr
du multi-octet caractères dans les paramètres régionaux actuels (généralement UTF8).Réponses:
Vous avez juste besoin de la
column
commande et lui dire d'utiliser des tabulations pour séparer les colonnesPour résoudre le problème de la "cellule vide", nous avons simplement besoin de l'
-n
option suivantecolumn
:Ma page de manuel de colonne indique
-n
une "extension Debian GNU / Linux". Mon système Fedora ne présente pas le problème des cellules vides: il semble provenir de BSD et la page de manuel indique "La version 2.23 a modifié l'option -s pour qu'elle ne soit pas gourmande"la source
column
, bien sûr; comment évident (avec le recul) +1 ... Merci ...column -s $'\t' -t
les cellules vides sont ignorées , toutes les cellules suivantes situées à droite de celle-ci (sur cette ligne) étant déplacées vers la gauche; c'est-à-dire à la suite d'une ligne blanche dans un fichier ouVous recherchez la
pr
commande pratique de dandy :Le "-e24" est "L'onglet Développer s'arrête à 24 espaces". Heureusement,
paste
place un caractère de tabulation entre les colonnes pourpr
pouvoir le développer. J'ai choisi 24 en comptant les caractères dans "Récursivement énumérable" et en ajoutant 2.la source
expand
commande directement:paste file1 file2 | expand -t 24
?sed
alors il y a un processus qui ne fonctionne pas. Il utilisepr
une commande ancienne datant des jours Unix SysV, je pense, donc il pourrait exister sur plus d’installations queexpand
. C'est juste la vieille école, en bref.Mise à jour : Voici un script beaucoup plus simple (celui à la fin de la question) pour la sortie sous forme de tableau. Il suffit de lui transmettre le nom du fichier comme vous le feriez pour
paste
... Il utilisehtml
pour créer le cadre, il est donc ajustable. Il conserve plusieurs espaces et l'alignement des colonnes est préservé lorsqu'il rencontre des caractères unicode. Cependant, la manière dont l'éditeur ou le visualiseur rend l'unicode est un tout autre problème ...---
Un résumé des outils présentés dans les réponses (jusqu'à présent).
Je les ai regardées de près. voici ce que j'ai trouvé:
paste
# Cet outil est commun à toutes les réponses présentées jusqu'à présent. # Il peut gérer plusieurs fichiers. donc plusieurs colonnes ... Bien! # Il délimite chaque colonne avec un onglet ... Bien. # Sa sortie n'est pas tabulée.Tous les outils ci-dessous suppriment tous ce délimiteur! ... Mauvais si vous avez besoin d'un délimiteur.
column
# Il supprime le délimiteur de tabulation, donc l'identification de champ est purement basée sur des colonnes qu'il semble gérer assez bien .. Je n'ai rien vu de mal ... # En plus de ne pas avoir de délimiteur unique, cela fonctionne bien!expand
# N'a qu'un seul paramètre de tabulation, de sorte qu'il est imprévisible au-delà de 2 colonnes. # L'alignement des colonnes n'est pas précis lors de la gestion d'unicode et il supprime le délimiteur de tabulation. L'identification de champ est donc purement par alignement de colonne.pr
# Ne comporte qu'un seul paramètre de tabulation, il est donc imprévisible au-delà de 2 colonnes. # L'alignement des colonnes n'est pas précis lors de la gestion de l'unicode et supprime le délimiteur de tabulation. L'identification du champ se fait donc uniquement par alignement de colonne.Pour moi,
column
c’est la meilleure solution évidente en tant que one-liner .. Si vous voulez soit le délimiteur, soit une tabluation ASCII-art de vos fichiers, lisez la suite, sinon ...columns
c’est sacrément bon:) ...Voici un script qui prend n’importe quel nombre de fichiers et crée une présentation sous forme de tableau ASCII-art. (Notez que l’unicode peut ne pas restituer la largeur attendue, par exemple. ௵, qui est un seul caractère. Ceci est très différent de la colonne. les nombres étant incorrects, comme dans certains des utilitaires mentionnés ci-dessus.) ... La sortie du script, illustrée ci-dessous, provient de 4 fichiers d'entrée, nommés F1 F2 F3 F4 ...
Voici ma réponse originale (coupé un peu au lieu du script ci-dessus)
Utiliser
wc
pour obtenir la largeur de colonne, etsed
pour pad droit avec un caractère visible.
(juste pour cet exemple) ... et ensuitepaste
pour joindre les deux colonnes avec un caractère de tabulation ...Si vous voulez remplir la colonne de droite:
la source
Tu y es presque.
paste
place un caractère de tabulation entre chaque colonne, il suffit donc de développer les onglets. (Je suppose que vos fichiers ne contiennent pas d'onglets.) Vous devez déterminer la largeur de la colonne de gauche. Avec (assez récent) utilitaires GNU,wc -L
affiche la longueur de la plus longue ligne. Sur d’autres systèmes, faites un premier passage avec awk. La+1
est la quantité d'espace vide que vous voulez entre les colonnes.Si vous avez l'utilitaire de colonne BSD, vous pouvez l'utiliser pour déterminer la largeur de la colonne et développer les onglets en une fois. (
␉
est un caractère de tabulation littéral; vous pouvez utiliser à la$'\t'
place, sous bash / ksh / zsh , et n'importe quel shell, vous pouvez utiliser"$(printf '\t')"
.)la source
wc
, la commande doit être:wc -L <left.txt
... parce que, quand un nom de fichier est spedified comme une ligne de commande arg , son nom est sortie stdoutCeci est multi-étapes, donc ce n'est pas optimal, mais voilà.
1) Trouvez la longueur de la plus longue ligne dans
file1.txt
.Avec votre exemple, la plus longue ligne est 22.
2) Utilisez awk pour pad
file1.txt
, en tapant chaque ligne de moins de 22 caractères jusqu'à 22 caractères avec l'printf
instruction.Remarque: Pour FS, utilisez une chaîne qui n'existe pas dans
file1.txt
.3) Utilisez la pâte comme avant.
Si c'est quelque chose que vous faites souvent, cela peut facilement être transformé en script.
la source
while IFS= read -r line
, sinon le shell modifiera les espaces et les barres obliques inverses. Mais le shell n'est pas le meilleur outil pour ce travail; les versions récentes de GNU coreutils ontwc -L
(voir la réponse de fred), ou vous pouvez utiliser awk:awk 'n<length {n=length} END {print +n}'
.Je ne peux pas commenter la réponse de Glenn Jackman, je l'ajoute donc pour résoudre le problème des cellules vides noté par Peter.O. L'ajout d'un caractère nul avant chaque onglet élimine les exécutions de délimiteurs traités comme une simple rupture et résout le problème. (À l'origine, j'avais utilisé des espaces, mais l'utilisation du caractère nul éliminait l'espace supplémentaire entre les colonnes.)
Si le caractère nul provoque des problèmes pour diverses raisons, essayez soit:
ou
Les deux
sed
etcolumn
semblent varier la mise en œuvre à travers les saveurs et les versions d'Unix / Linux, BSD en particulier (et Mac OS X) par rapport à GNU / Linux.la source
od -c
et je ne vois aucun octet nul. Ceci est sur centos et Ubuntu.\0
ne fonctionnait pas en tant que tellenull
, mais elle le\x0
faisait. Cependant, alors la colonne a donné uneline too long
erreur. La chose la plus simple semble être d'utiliser un espace et de vivre avec le personnage supplémentaire.S'appuyant sur la réponse de bahamat : cela peut être entièrement fait en
awk
lisant les fichiers une seule fois et en ne créant aucun fichier temporaire. Pour résoudre le problème comme indiqué, faitesComme beaucoup de
awk
scripts de ce type, le premier est lufile1
, en enregistrant toutes les données dusave
tableau et en calculant simultanément la longueur de ligne maximale. Ensuite, il litfile2
et affiche lesfile1
données sauvegardées ( ) côte à côte avec lesfile2
données actuelles ( ). Enfin, sifile1
est plus long quefile2
(a plus de lignes), nous imprimons les dernières lignes defile1
(celles pour lesquelles il n'y a pas de ligne correspondante dans la deuxième colonne).En ce qui concerne le
printf
format:"%-nns"
imprime une chaîne justifiée à gauche dans un champ denn
caractères large."%-*s", nn
fait la même chose - le lui*
dit de prendre la largeur du champ du paramètre suivant.maxlength+2
nn
+2
Le script ci-dessus ne fonctionne que pour deux fichiers. Il peut être modifié de manière triviale pour gérer trois fichiers, ou quatre, etc., mais cela serait fastidieux et laissé comme exercice. Cependant, il n’est pas difficile de le modifier pour gérer un nombre quelconque de fichiers:
Ceci est très similaire à mon premier script, sauf
max_length
en tableau.max_FNR
en tableau.save
en un tableau à deux dimensions.END
bloc.la source
paste
c'est la meilleure solution. en particulier, Glenn Jackmanpaste file1 file2 | column -s $'\t' -t
. Mais j'ai pensé que ce serait amusant d'essayer d'améliorer l'awk
approche.