Afficher deux fichiers côte à côte

Comment 2 fichiers texte non triés de différentes longueurs peuvent-ils être affichés côte à côte (en colonnes) dans un shell

Donnée one.txt et two.txt:

$ cat one.txt
apple
pear
longer line than the last two
last line

$ cat two.txt
The quick brown fox..
foo
bar 
linux

skipped a line

Affichage:

apple                               The quick brown fox..
pear                                foo
longer line than the last two       bar 
last line                           linux

                                    skipped a line

paste one.txt two.txt fait presque l'affaire mais n'a pas bien aligné les colonnes car il imprime juste un onglet entre les colonnes 1 et 2. Je sais comment faire avec emacs et vim mais je veux que la sortie soit affichée sur stdout pour la tuyauterie ect.

La solution que j'ai trouvée utilise sdiff puis des tuyaux pour sed pour supprimer la sortie sdiff ajoute.

sdiff one.txt two.txt | sed -r 's/[<>|]//;s/(t){3}//'

Je pourrais créer une fonction et le coller dans mon .bashrc, mais sûrement une commande pour cela existe déjà (ou un nettoyant solution potentiellement)?

76
demandé sur Chris Seymour 2012-11-12 14:15:29

9 réponses

Vous pouvez utiliser pr pour ce faire, en utilisant l'indicateur -m pour fusionner les fichiers, un par colonne, et -t pour omettre les en-têtes, par exemple.

pr -m -t one.txt two.txt

Sorties:

apple                               The quick brown fox..
pear                                foo
longer line than the last two       bar
last line                           linux

                                    skipped a line
137
répondu Hasturkun 2012-11-12 12:44:51

Pour développer un peu la réponse de @Hasturkun: par défaut, pr n'utilise que 72 colonnes pour sa sortie, mais il est relativement facile de le faire utiliser toutes les colonnes disponibles de votre fenêtre de terminal:

pr -w $COLUMNS -m -t one.txt two.txt

La plupart des shell vont stocker (et mettre à jour) la largeur d'écran de votre terminal dans la variable d'environnement $COLUMNS, donc nous passons simplement cette valeur à pr pour l'utiliser pour le paramètre de largeur de sortie.

Cela répond également à la question de @Matt:

Est là une façon pour pr de détecter automatiquement la largeur de l'écran?

Donc, non: pr lui-même ne peut pas détecter la largeur d'écran, mais nous aidons un peu en passant dans la largeur du terminal via l'option -w.

25
répondu pvandenberk 2017-05-23 12:10:27
paste one.txt two.txt | awk -F'\t' '{
    if (length($1)>max1) {max1=length($1)};
    col1[NR] = $1; col2[NR] = $2 }
    END {for (i = 1; i<=NR; i++) {printf ("%-*s     %s\n", max1, col1[i], col2[i])}
}'

L'utilisation de * dans une spécification de format vous permet de fournir la longueur du champ dynamiquement.

6
répondu Barmar 2012-11-12 10:47:54

Si vous connaissez les fichiers d'entrée ont pas d'onglets, puis à l'aide de expand simplifie @oyss's réponse:

paste one.txt two.txt | expand --tabs=50

S'il peut y avoir des onglets dans les fichiers d'entrée, vous pouvez toujours développer en premier:

paste <(expand one.txt) <(expand two.txt) | expand --tabs=50
5
répondu Bob 2017-05-23 12:34:42

Supprimer dynamiquement le comptage de longueur de champ de la réponse de Barmar en fera une commande beaucoup plus courte....mais vous avez encore besoin d'au moins un script pour terminer le travail qui ne pouvait être évitée peu importe la méthode que vous choisissez.

paste one.txt two.txt |awk -F'\t' '{printf("%-50s %s\n",$1,$2)}'
2
répondu oyss 2012-11-12 12:29:55

Il y a un moyen sed:

f1width=$(wc -L <one.txt)
f1blank="$(printf "%${f1width}s" "")"
paste one.txt two.txt |
    sed "
        s/^\(.*\)\t/\1$f1blank\t/;
        s/^\(.\{$f1width\}\) *\t/\1 /;
    "

(Bien sûr, la solution de @ Hasturkun prest la la plus précise!):

1
répondu F. Hauri 2013-01-04 14:49:00

Si vous voulez connaître la différence réelle entre deux fichiers, utilisez la commande ci-dessous

diff -y file1.cf file2.cf

Vous pouvez également définir la largeur pour imprimer les colonnes à l'aide de l'option -W, --width=NUM:

diff -y -W 150 file1.cf file2.cf
1
répondu user3498040 2015-01-12 10:35:44
diff -y <file1> <file2>


[root /]# cat /one.txt
apple
pear
longer line than the last two
last line
[root /]# cat /two.txt
The quick brown fox..
foo
bar
linux
[root@RHEL6-64 /]# diff -y one.txt two.txt
apple                                                         | The quick brown fox..
pear                                                          | foo
longer line than the last two                                 | bar
last line                                                     | linux
0
répondu iAdhyan 2014-01-01 12:07:55

Trouvez ci-dessous une solution basée sur python.

import sys

# Specify the number of spaces between the columns
S = 4

# Read the first file
l0 = open( sys.argv[1] ).read().split('\n')

# Read the second file
l1 = open( sys.argv[2] ).read().split('\n')

# Find the length of the longest line of the first file
n = len(max(l0, key=len))

# Print the lines
for i in  xrange( max( len(l0), len(l1) ) ):

    try:
        print l0[i] + ' '*( n - len(l0[i]) + S) + l1[i]
    except:
        try:
            print ' ' + ' '*( n - 1 + S) + l1[i]
        except:
            print l0[i]

Exemple

apple                            The quick brown fox..
pear                             foo
longer line than the last two    bar 
last line                        linux

                                 skipped a line
0
répondu funk 2016-01-29 15:01:00