Во-первых, ошибочно использовать символ вертикальной черты, чтобы узнать, где поля начинаются и заканчиваются -у вас уже есть строка, которая точно определяет их, и нет никаких шансов, что содержимое поля будет содержать тот же символ, что и разделитель полей. :первая строка, содержащая только маркеры столбцов(+
)и символы-заполнители(-
).
Вот Perl-скрипт(table-to-csv.pl
)для извлечения данных и их печати в виде файла в формате csv. Учитывая, что входные данные являются определением таблицы sql, оно заключает в кавычки каждое поле данных -, более общая версия может попытаться определить, необходимо ли заключать в кавычки (, т. е. является ли поле числовым или нет ).
Этот скрипт немного сложнее, чем он должен быть на самом деле, т.е. нет реальной необходимости создавать массивы @headers
и @data
, когда длины столбцов известны, каждую строку можно просто извлечь и распечатать по мере их считывания. Такой способ упрощает дальнейшую обработку. для одного или обоих заголовков и данных, если это необходимо.
#!/usr/bin/perl -w
use strict;
my @columns = ();
my @headers = ();
my @data = ();
sub extract; # forward declaration of extract subroutine
# main loop
while(<>) {
chomp;
next if (m/^\s*$/);
if(/^\+-/) {
# use the '+' chars in the first line to find column positions
next if (@columns != 0);
my $i=0;
while ($i >= 0 && $i < length($_)) {
my $e=index($_,"+",$i+1);
# store starting pos & length pair for each column
push @columns, [ $i+2, $e-3-$i ];
$i=$e;
};
pop @columns; # last pair will always be bogus, dump it.
} else { # extract the headers and data
if (!@headers) {
@headers = extract($_,@columns); # array of field header names
} else {
push @data, [ extract($_,@columns) ]; # array of arrays of field data
};
};
};
# output in simple csv format.
print join(',',@headers), "\n";
foreach my $l (@data) {
print join(',',@{ $l }), "\n";
};
### subroutines
sub extract {
my ($line,@cols) = @_;
my @f=();
foreach my $c (@cols) {
my $d = substr($line,$c->[0],$c->[1]);
$d =~ s/^\s*|\s*$//g; # strip leading & trailing spaces
push @f, '"'. $d.'"' ;
}
return @f;
};
Вывод:(с вашей входной таблицей, сохраненной как table.txt)
$./table-to-csv.pl table.txt
"Field","Type","Null","Key","Default","Extra"
"id","int(11)","NO","PRI","NULL",""
"foo","varchar(10)","YES","","NULL",""
Вторая часть вашего вопроса требует небольшой сложности построения массива @data
. Чтение и синтаксический анализ CSV прост, особенно если вы используете библиотеку, такую как модуль Perl Text::CSV
, для обработки полей в кавычках и без кавычек... но для правильного формата вывода вам нужно два прохода через данные.Первый для нахождения и сохранения наибольшей ширины каждого поля (, который используется для управления форматом вывода ), а второй для печати данных.
Для следующего perl-скрипта(csv-to-table.pl
)требуется модуль Text::CSV
. В системах debian и т. д. это находится в пакете libtext-csv-perl
. Другие дистрибутивы будут иметь похожие имена пакетов. Или вы можете установить его самостоятельно с помощью cpan
.
#!/usr/bin/perl -w
use strict;
use Text::CSV;
my @data;
my @lengths;
my $csv = Text::CSV->new ();
while (my $row = $csv->getline(*ARGV)) {
my @fields = @$row;
foreach my $i (0..@fields-1) { # find the largest width for each field
my $len = length($fields[$i]);
$lengths[$i] = $len if (!defined($lengths[$i]) || $lengths[$i] <= $len);
};
push @data, [ @fields ]; # stuff each record into an array of arrays
};
my $hdr='+';
my $fmt='';
foreach (@lengths) {
# build the header/separator line and the printf format string
$hdr.= '-' x ($_+2). '+';
$fmt.= '| %-'. ($_). 's ' ;
};
$fmt.= "|\n";
$hdr.= "\n";
# output the table
print $hdr;
printf "$fmt", @{ $data[0] };
print $hdr;
foreach my $i (1..@data-1) {
printf $fmt, @{ $data[$i++] };
}
print $hdr;
Выход:
$./table-to-csv.pl table.txt |./csv-to-table.pl
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| foo | varchar(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
pacman
сообщает вам, что не может обновить систему, потому что не может обновить пакет без нарушения зависимости.
У вас установлен пакет с именем pamac-qt
. Этот пакет указан как «экспериментальный » и несовместим с API pamac 9 . Вам нужно будет заменить его на pamac-gtk
.
Это должно решить вашу проблему:
pacman -S pamac-gtk
pacman -R pamac-qt