У меня есть два текстовых файла. Первый имеет содержание:
Languages
Recursively enumerable
Regular
в то время как второй имеет содержание:
Minimal automaton
Turing machine
Finite
Я хочу объединить их в один файл по столбцам. Итак, я попытался, paste 1 2
и его вывод:
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Однако я хотел бы, чтобы столбцы были хорошо выровнены, например:
Languages Minimal automaton
Recursively enumerable Turing machine
Regular Finite
Мне было интересно, если бы можно было достичь этого без ручной обработки?
Добавлено:
Вот еще один пример, где метод Брюса почти прибивает его, за исключением небольшого смещения, о котором я удивляюсь, почему?
$ 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
иexpand
...columns
избегаю этой проблемы.➀ unicode may render oddly
but the column count is ok
безусловно , делает не применяется кwc-paste-pr
иwc-paste-pr
они показать разницу в количестве столбцов .. Остальные в порядке.pr
многобайтовыми символы в текущей локали (обычно UTF8).Ответы:
Вам просто нужна
column
команда, и скажите ей использовать вкладки для разделения столбцовДля решения «пустая ячейка» противоречия, мы просто нужна
-n
опцияcolumn
:На странице man моей колонки указано
-n
«Расширение Debian GNU / Linux». В моей системе Fedora нет проблемы с пустыми ячейками: похоже, она получена из BSD, а на странице руководства написано, что «Версия 2.23 изменила опцию -s как не жадную»источник
column
конечно; насколько очевидно (задним числом) +1 ... Спасибо ...column -s $'\t' -t
игнорирует пустые ячейки , в результате чего все последующие ячейки справа от него (в этой строке) перемещаются влево; то есть в результате пустой строки в файле, или она была короче ... :(Вы ищете удобную
pr
команду денди :«-E24» означает «развернуть табуляцию до 24 пробелов». К счастью,
paste
ставит символ табуляции между столбцами, чтобыpr
можно было его развернуть. Я выбрал 24, посчитав символы в «Recursively enumerable» и добавив 2.источник
expand
команду непосредственно:paste file1 file2 | expand -t 24
?sed
поэтому есть один процесс, который не запускается.pr
Я думаю, он использует древнюю команду, относящуюся к дням Unix SysV, поэтому он может существовать при большем количестве установок, чемexpand
. Короче, это просто старая школа.Обновление : здесь гораздо более простой скрипт (тот, что в конце вопроса) для табличного вывода. Просто передайте ему имя файла, как вы бы
paste
... Он используетhtml
для создания фрейма, так что он настраивается. Он сохраняет несколько пробелов, и выравнивание столбцов сохраняется, когда встречаются символы Юникода. Однако то, как редактор или зритель отображает юникод, это совсем другое дело ...---
Краткий обзор инструментов, представленных в ответах (пока).
Я довольно внимательно посмотрел на них; вот что я нашел:
paste
# Этот инструмент является общим для всех представленных ответов # Он может обрабатывать несколько файлов; поэтому несколько столбцов ... Хорошо! # Разграничивает каждый столбец с помощью табуляции ... Хорошо. # Его вывод не сведен в таблицу.Все инструменты ниже всех удаляют этот разделитель! ... Плохо, если вам нужен разделитель.
column
# Он удаляет разделитель табуляции, поэтому поле идентифицируется исключительно по столбцам, которые, кажется, обрабатываются довольно хорошо ... Я не заметил ничего неправильного ... # Помимо отсутствия уникального разделителя, он работает отлично!expand
# Имеет только одну настройку вкладки, поэтому она непредсказуема за пределами 2 столбцов # Выравнивание столбцов не является точным при обработке юникода, и оно удаляет разделитель табуляции, поэтому идентификация полей производится исключительно выравниванием столбцовpr
# Имеет только одну настройку вкладки, поэтому она непредсказуема за пределами 2 столбцов. # Выравнивание столбцов не является точным при обработке юникода, и оно удаляет разделитель табуляции, поэтому поле идентифицируется исключительно по выравниванию столбцаДля меня
column
это очевидный лучший солютон в качестве однострочного. Если вы хотите использовать разделитель или ASCII-арт табуляцию ваших файлов, читайте дальше, иначе ...columns
чертовски хорошо :) ) ...Вот скрипт, который принимает любой номер файла и создает табличную презентацию в стиле ASCII. (Имейте в виду, что юникод может не отображаться до ожидаемой ширины, например, ௵, который представляет собой один символ. Это сильно отличается от столбца неверные числа, как в некоторых из утилит, упомянутых выше.) ... Вывод скрипта, показанный ниже, получен из 4 входных файлов с именем F1 F2 F3 F4 ...
Вот мой оригинальный ответ (немного урезанный вместо вышеприведенного сценария)
Используется
wc
для получения ширины столбца иsed
для правой панели с видимым символом.
(только для этого примера) ... и затемpaste
для объединения двух столбцов с символом табуляции ...Если вы хотите выделить правую колонку:
источник
Ты почти там.
paste
помещает символ табуляции между каждым столбцом, поэтому все, что вам нужно сделать, это развернуть вкладки. (Я предполагаю, что ваши файлы не содержат вкладок.) Вам нужно определить ширину левого столбца. С (достаточно недавно) утилитами GNU,wc -L
показывает длину самой длинной строки. В других системах сделайте первый проход с помощью awk.+1
Это количество пустого пространства , которое вы хотите между колоннами.Если у вас есть утилита для столбцов BSD, вы можете использовать ее, чтобы определить ширину столбцов и развернуть вкладки за один раз. (
␉
является буквальным символом табуляции;$'\t'
вместо bash / ksh / zsh вы можете использовать его и в любой оболочке, которую можете использовать"$(printf '\t')"
.)источник
wc
команда должна быть:wc -L <left.txt
... потому что, когда имя файла ускоряется как аргумент командной строки arg , его имя выводится на стандартный выводЭто многошаговое, так что это не оптимально, но здесь идет.
1) Найдите длину самой длинной строки в
file1.txt
.В вашем примере самая длинная строка - 22.
2) Используйте awk для
file1.txt
заполнения, добавляя в каждую строку менее 22 символов до 22 сprintf
оператором.Примечание: для FS используйте строку, которая не существует в
file1.txt
.3) Используйте пасту, как вы делали раньше.
Если это то, что вы делаете часто, это легко можно превратить в сценарий.
источник
while IFS= read -r line
, в противном случае оболочка будет искажать пробелы и обратные косые черты. Но оболочка не лучший инструмент для этой работы; Последние версии GNU Coreutils естьwc -L
(см ответ Фреда), или вы можете использовать AWK:awk 'n<length {n=length} END {print +n}'
.Я не могу комментировать ответ Гленна Джекмана, поэтому добавляю его, чтобы решить проблему пустых ячеек, которую заметил Питер. Добавление нулевого символа перед каждой вкладкой исключает использование разделителей, которые рассматриваются как один разрыв, и устраняет проблему. (Первоначально я использовал пробелы, но использование нулевого символа исключает лишний пробел между столбцами.)
Если нулевой символ вызывает проблемы по разным причинам, попробуйте либо:
или же
И то,
sed
и другое, по-column
видимому, различаются по реализации в разных версиях и версиях Unix / Linux, особенно BSD (и Mac OS X) по сравнению с GNU / Linux.источник
od -c
и не вижу нулевых байтов. Это на Centos и Ubuntu.\0
не работало какnull
sed, но работало\x0
. Однако тогда столбец выдалline too long
ошибку. Кажется, проще всего использовать пробел и жить с дополнительным персонажем.Опираясь на ответ Багамата : это можно сделать целиком
awk
, читая файлы только один раз и не создавая никаких временных файлов. Чтобы решить проблему, как указано, сделайтеКак и во многих
awk
подобных сценариях, вышеупомянутое сначала читаетfile1
, сохраняя все данные вsave
массиве и одновременно вычисляя максимальную длину строки. Затем он читаетfile2
и печатает сохраненные (file1
) данные рядом с текущими (file2
) данными. Наконец, еслиfile1
он длиннееfile2
(имеет больше строк), мы печатаем последние несколько строкfile1
(те, для которых нет соответствующей строки во втором столбце).Что касается
printf
формата:"%-nns"
печатает строку, выровненную по левому краю в полеnn
символов шириной."%-*s", nn
делает то же самое - команда*
говорит, что нужно взять ширину поля из следующего параметра.maxlength+2
nn
+2
Приведенный выше скрипт работает только для двух файлов. Его можно легко изменить для обработки трех файлов или для обработки четырех файлов и т. Д., Но это было бы утомительно и оставлено в качестве упражнения. Однако, оказывается, не должно быть трудно изменить его , чтобы обработать любое количество из файлов:
Это очень похоже на мой первый сценарий, кроме
max_length
в массив.max_FNR
в массив.save
в двумерный массив.END
блока.источник
paste
это лучшее решение; в частности, Гленн Джекманpaste file1 file2 | column -s $'\t' -t
. Но я подумал, что было бы интересно попытаться улучшитьawk
подход.