Как очистить столбцы с несогласованными в тексте?
У меня есть программа на C, которая выводит два столбца, совершенно несогласованных. Причиной несоосности является длина слов в первом столбце, очень разные.
У меня есть выходной файл, открытый в vi. Как быстро выровнять эти два столбца? Я в порядке с использованием awk, perl, sed, а не только инструментария vi (7.2). Кроме того, можем ли мы иметь общее решение для файлов с более чем двумя столбцами?
Вот пример файла
column1 column2
------- -------
sdfsdfsddfsdfsdfsdfsd 343r5
dfgdfgdf 234
gdfgdfgdfgdfgf 645
Ответы
Ответ 1
Предположительно, вы используете printf
для вывода столбцов в первую очередь. Вы можете использовать дополнительные модификаторы в своей строке формата, чтобы убедиться, что все получилось.
- Чтобы напечатать столбец определенной ширины (с выравниванием по правому краю), добавьте ширину перед флагом форматирования, например, "% 10s" напечатает столбец шириной 10. Если ваша строка длиннее 10 символов, столбец будет больше, чем вы хотите, поэтому выберите максимальное значение. Если строка короче, она будет дополнена пробелами.
- Чтобы выравнивать по левому краю столбец, поставьте знак "впереди", например "% -10s". Мне нравится выравнивать строки и правильно выравнивать числа лично.
- Если вы печатаете адреса, вы можете изменить символы заполнения от пробелов до нулей с нулевым значением: "% 010x".
Чтобы привести более подробный пример:
printf("%-30s %8s %8s\n", "Name", "Address", "Size");
for (i = 0; i < length; ++i) {
printf("%-30s %08x %8d\n", names[i], addresses[i], sizes[i]);
Это напечатает три столбца:
Name Address Size
foo 01234567 346
bar 9abcdef0 1024
something-with-a-longer-name 0000abcd 2048
Ответ 2
Для быстрого и грязного исправления проведите его через столбец:
your_program | column -t
Если вам нужно включить пробелы в данные столбца, затем разделите поля на некоторый символ, например "|" и:
your_program | column -t -s "|"
Вы можете использовать любой символ для разделителя и указать его с помощью ключа -s. Управляющие символы возможны, но немного сложнее работать.
Но, как сказал Джей, вам лучше исправить вашу программу, чтобы правильно отформатировать результат.
Ответ 3
Здесь awk-решение: c_prog | awk '{ printf("%- 40s %- 40s\n", $1, $2); }'
Ответ 4
Если вы хотите выполнить обработку в Vim (в отличие от фиксации генератора), установите superb align plugin и выполните следующие действия:
ggVG
\tsp
Первая команда разбивается на gg
(перейдите к началу файла), V
(введите режим визуальной линии), G
(перейдите в конец файла). В качестве комбинации он визуально выбирает весь файл. \tsp
- это выравнивающая карта, которая выравнивается по белому пространству.
Если вы предпочитаете делать что-то в командной строке :
, вы можете использовать альтернативный разделитель (например, ###
) и использовать строку командной строки Align:
:%s/\s\+/###/g
:%Align ###
:%s/### //g
Это длиннее, но вы можете найти его более логичным/запоминающимся.
Ответ 5
Я написал небольшую программу, которая решает эту проблему с помощью Perl. Он также работает для нескольких столбцов.
#!/usr/bin/perl
use strict;
use warnings;
my $sep = 2;
sub max {
my ($a,$b) = @_;
return $a > $b ? $a : $b;
}
my @rows;
my $cols;
my $max = 0;
while (<>) {
next if m/^\s*$/;
my (@cols) = split m'\s+';
for (@cols) {
$max = max($max, length);
}
$cols = @cols;
push @rows, \@cols;
}
for (@rows) {
my $str = join '', (('%-' . ($max+$sep) . 's') x $cols);
$str .= "\n";
printf $str, @$_;
}
Ответ 6
Я просто добавляю отсутствующие в других вариантах ответов:
Emacs с Mx align-regexp, Mx align-string и т.д. подробнее на http://www.emacswiki.org/emacs/AlignCommands
Командная оболочка POSIX (возможно, встроенная) printf:
while read f1 f2 f3 tail; do printf "%10s %5s | %s" $f1 $f3 $tail; done <file.txt