Отображать два файла бок о бок

Как два несортированных текстовых файла разных длин будут отображаться бок о бок (в столбцах) в shell

Учитывая one.txt и 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

Дисплей:

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 почти делает трюк, но не выравнивает столбцы красиво, поскольку он просто печатает одну вкладку между столбцами 1 и 2. Я знаю, как это сделать с emacs и vim, но хочу, чтобы выходные данные выводились на stdout для ect трубопровода.

В решении, которое я придумал, используется sdiff, а затем выполняется переход к sed для удаления выходных данных sdiff.

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

Я мог бы создать функцию и вставить ее в свой .bashrc, но, конечно, для этого уже существует команда (или потенциально возможное решение для очистки)?

Ответ 1

Для этого вы можете использовать pr, используя флаг -m для объединения файлов, по одному на столбец, и -t для -t заголовков, например.

pr -m -t one.txt two.txt

выходы:

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

                                    skipped a line

Смотрите также:

Ответ 2

Чтобы немного раскрыть ответ @Hasturkun: по умолчанию pr использует только 72 столбца для вывода, но относительно легко использовать все доступные столбцы окна вашего терминала:

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

В большинстве случаев оболочка будет сохранять (и обновлять) ширину экрана вашего терминала в переменной среды $COLUMNS, поэтому мы просто передаем это значение на pr, чтобы использовать его настройку ширины вывода.

Это также отвечает на вопрос @Matt:

Есть ли способ для автоматического определения ширины экрана?

Итак, no: pr сам не может определить ширину экрана, но мы немного помогаем, пропуская в терминале ширину с помощью опции -w.

Ответ 3

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])}
}'

Использование * в спецификации формата позволяет вам динамически задавать длину поля.

Ответ 4

Если вы знаете, что входные файлы не имеют вкладок, использование expand упрощает @oyss ответ

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

Если во входных файлах могут быть вкладки, вы всегда можете развернуть сначала:

paste <(expand one.txt) <(expand two.txt) | expand --tabs=50

Ответ 5

удалить динамическую длину поля, исходя из ответа Barmar, сделает ее намного более короткой командой.... но вам все равно потребуется хотя бы один script, чтобы завершить работу, которой не удалось избежать, независимо от того, какой метод вы выберете.

paste one.txt two.txt |awk -F'\t' '{printf("%-50s %s\n",$1,$2)}'

Ответ 6

Существует способ 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 /;
    "

(Конечно, решение @Hasturkun pr является самым точным!):

Ответ 7

Если вы хотите узнать реальную разницу между двумя файлами рядом, используйте diff -y:

diff -y file1.cf file2.cf

Вы также можете установить ширину вывода, используя -W, --Width=NUM:

diff -y -W 150 file1.cf file2.cf

и чтобы вывод столбца diff соответствовал текущему окну терминала:

diff -y -W $COLUMNS file1.cf file2.cf

Ответ 8

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
[[email protected] /]# diff -y one.txt two.txt
apple                                                         | The quick brown fox..
pear                                                          | foo
longer line than the last two                                 | bar
last line                                                     | linux

Ответ 9

Найдите ниже решение на основе 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]

Пример

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

                                 skipped a line