Отображать два файла бок о бок
Как два несортированных текстовых файла разных длин будут отображаться бок о бок (в столбцах) в 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