Відображення двох файлів поруч


94

Як можна відображати 2 несортовані текстові файли різної довжини поруч (у стовпцях) в ashell

Дано 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а потім труби для видалення вихідних даних sdiff.

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

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


Не в оболонці, але варто згадати: використовуйте meld !
Fedorqui 'SO prestani шкодити'

Відповіді:


166

Ви можете prце зробити, використовуючи -mпрапор для об’єднання файлів, по одному на стовпець, і -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

Дивитися також:


15
Ідеально! Знав, що щось існує, ніколи prраніше не чув . Я спробував із 3 файлами, і результат був усічений, але -wваріант вирішив це. Приємна відповідь.
Chris Seymour

5
@sudo_o: Радий допомогти, coreutils повний самоцвітів
Гастуркун,

1
Чи є спосіб для PR автоматично визначити ширину екрана?
Метт,

2
@Matt: Ви можете використовувати $COLUMNS, що має забезпечуватися оболонкою.
Гастуркун,

1
Коли використовується для друку двох файлів поруч, prвирізає кінець довгих рядків. Чи є спосіб змусити його обернути рядки?
молнарг

32

Щоб трохи розширити відповідь @Hasturkun : за замовчуванням prдля виведення використовує лише 72 стовпці, але порівняно легко змусити його використовувати всі доступні стовпці вашого вікна терміналу:

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

Більшість оболонок зберігатимуть (і оновлюватимуть) ширину екрана вашого терміналу у змінній $COLUMNSсередовища, тому ми просто передаємо це значення на prвикористання для налаштування ширини виводу.

Це також відповідає на запитання @Matt :

Чи є спосіб для PR автоматично визначити ширину екрана?

Отже, ні: prсам не може виявити ширину екрану, але ми трохи допомагаємо, передаючи ширину терміналу через -wопцію.


7

Якщо ви знаєте , що вхідні файли не мають вкладок, а потім з допомогою expandСпрощує @oyss «S відповіді :

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

Якщо у вхідних файлах можуть бути вкладки, ви завжди можете спочатку розгорнути їх:

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

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

Використання *у специфікації формату дозволяє динамічно подавати довжину поля.


1
Ніколи не казав, що так, але якщо я хочу час від часу відображати два файли поруч, тоді це diff -y one.txt two.txtробить кращу роботу, ніж paste one.txt two.txtвидалення зайвих символів, які відображаються, sedє тривіальним порівнянням із написанням / запам'ятовуванням awkсценарію. Навіть якщо обидві функції виконуються .bash_rcдовше! = Краще, читабельніше, швидше .. яка тут перевага?
Кріс Сеймур

2

видалити динамічно підрахунок довжини поля з відповіді Бармара зробить це набагато коротшою командою .... але вам все одно потрібен принаймні один сценарій, щоб закінчити роботу, якої не уникнути, незалежно від того, який метод ви вибрали.

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

2

Якщо ви хочете дізнатися фактичну різницю між двома файлами поруч, використовуйте 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

2

Є 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 /;
    "

Під , ви можете використовувати printf -v:

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

(Звичайно, рішення @Hasturkun prє найточнішим !) :

Перевага sedнадpr

Ви можете точно вибрати ширину розділення та або сепаратори:

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

Або, для зразка, позначити рядки, що містять line:

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

відтворить:

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

1

Знайдіть нижче рішення на основі 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

0
diff -y <file1> <file2>


[root /]# cat /one.txt
яблуко
груша
довший рядок, ніж останні два
останній рядок
[root /]# cat /two.txt
Швидка бура лисиця ..
foo
бар
Linux
[root@RHEL6-64 /]# diff -y one.txt two.txt
яблуко | Швидка коричнева лисиця ..
груша | foo
довший рядок, ніж останні два | бар
останній рядок | Linux

sdiffце те, diff -yщо я обговорюю у питанні.
Кріс Сеймур

Так, правильно ... було згадано, щоб показати іншу команду / прапорець, що це робить.
iAdhyan

Але це не відповідає на запитання, diffдодає символи між двома файлами.
Кріс Сеймур
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.