Как поместить фиксированную ширину, вертикально ориентированную на пары "ключ-значение" в файле CSV?

необходимо использовать setkeycodes присваивать код клавиши.

http://www.jveweb.net/en/archives/2011/01/configure-unrecognized-keys-in-linux.html

скэн-код ключей был нераспознанным, это, никакой код клавиши, как не находили, был связан со скэн-кодом, важное значение здесь появляется прямо рядом с командой setkeycodes. Таким образом, необходимо определить e00b

узнайте неиспользованный код клавиши с

xmodmap -pke | less

и затем присвойте код клавиши с командой

setkeycodes

2
18.04.2014, 20:46
3 ответа

Или можно использовать regex подпрограммы Perl:

my $grammar = qr!
    ( ?(DEFINE)
       (?<Identifier> [^=\n]+ )
       (?<Statement>
           (?: # Begin alternation
               " #Opening quotes
               [^"]+? # Any non-quotes (including a new line)
               " # Closing quotes
              | [^\n]+ # Or a single line
           )   # End alternation
        )   

   )

!x;

my $file = do { local $/; <> }; #Slurp file named on command line
my %columns;
while( $file =~ 
   m{ ((?&Identifier))[\t ]*=[ \t]*((?&Statement)) $grammar}xgc )
{ 
   my ($header,$value) = ($1,$2);

       # Remove leading spaces and quote variable if it contains commas:
   for($header,$value) { s/^\s+//mg; /,/ and s/^|$/"/g }

       # Substitute \n with \\n to make multi-line values single-line:
   for($value) { chomp; s/\n/\\n/g }

   $columns{$header}=$value
}

print join "," => sort keys %columns; # Print column headers
print "\n";
print join "," => map { $columns{$_} } sort keys %columns; # Column content
print "\n";

Вызовите его как так:

[user@host]$ /path/to/script.pl /path/to/file.txt

Это распечатает к стандартному выводу отформатированную CSV таблицу

Это предполагает, что многострочный оператор не будет содержать двойных кавычек (") кроме его открытия и заключительных.

0
27.01.2020, 22:23
  • 1
    Вы работа над этим также? –  slm♦ 20.10.2013, 16:27
  • 2
    @slm Вы имеете в виду regex подпрограммы? Я только недавно узнал о них. Довольно мощный материал! –  Joseph R. 20.10.2013, 22:04
  • 3
    Нет, я просто думал, что это было забавно, что Вы и я отправили наши ответы на этот Q примерно в то же время, и мы подошли w/решения для Perl 8-). –  slm♦ 20.10.2013, 22:48
  • 4
    @slm я на самом деле отправил свой ответ после чтения Вашего. Вы perl- ceptioned я :) –  Joseph R. 20.10.2013, 22:58
  • 5
    ! Я делаю это слишком иногда, где я вижу пример и переосмысливаю его на другом языке или технике только, чтобы видеть, могу ли я сделать это. Я должен буду испытать regex подпрограммы также. Никогда не использовал их прежде. –  slm♦ 20.10.2013, 23:10

Хорошо это не симпатично, но делает, как Вы просите. Я записал сценарий в Perl, который возьмет вышеупомянутый файл и проанализирует его и затем использует модуль Text::CSV преобразовать его в формат CSV.

Сценарий

#!/usr/bin/env perl

use Text::CSV;

open(my $fh, "<data.txt");
@lines = <$fh>;
close ($fh);

my (%csv, $name, $val);

foreach my $line (@lines) {
  if ($line =~ m/=/) {
    chomp($line);
        $line =~ s/^\s+//g;
    ($name, $val) = split(/ = /, $line);
        $val =~ s/^"$//;
        $csv{$name} = $val;
  } else {
        $line =~ s/^\s+//g;
        $line =~ s/\s+$/\\n/g;
        $line =~ s/ "\\n$//;
        $csv{$name} .= $line;
  }
}

my @vals;
foreach my $i (sort keys %csv) {
  push(@vals, $csv{$i});
}

my $ccsv = Text::CSV->new();
$ccsv->combine(sort keys %csv);
$ccsv->parse($ccsv->string());
print $ccsv->string() . "\n";
$ccsv->combine(@vals);
$ccsv->parse($ccsv->string());
print $ccsv->string() . "\n";

Пример

Просто выполните его как это:

$ ./csv.pl
"Additional Text","Alarm Origin","Alarm Type","Clearance Time Stamp","Close Time Stamp","Creation Timestamp",Domain,"Event Time","Last Modification Timestamp","Managed Object","Notification Identifier","Original Event Time","Original Severity","Perceived Severity","Previous State","Probable Cause","Specific Problems","Target Entities","Termination Time Stamp"
"nativeProbableCause: Attempt Threshold Crossed\nosTime: 20131018163727.250+0530\nneTime: 20131011174021.0+0530\nnotificationId: AMS:160315\nportNumber:\nftpNumber:\nmeNm: INGJJMGRJMTSNB0001AG2OLT001\nmdNm: AMS\nobjectType: OT_MANAGED_ELEMENT\naliasValue: MGMT Security\nAccess:INGJJMGRJMTSNB0001AG2OLT001:IP10.70.6.6.T0.S841",IncomingAlarm,CommunicationsAlarm,"Fri 18 Oct 2013 05:01:40","Fri 18 Oct 2013 05:01:46","Fri 18 Oct 2013 04:37:29","Domain VMD1HTE1A71_ns:.dm.GJ_OAD2","Fri 18 Oct 2013 05:01:40","Fri 18 Oct 2013 05:01:46","Alcatel_5529OAD VMD1HTE1A71_ns:.OAD2 MD ""AMS"" Node ""INGJJMGRJMTSNB0001AG2OLT001""",160315,"Fri 11 Oct 2013 05:40:21",Major,Major,Outstanding,Unknown,"{  }","{ Alcatel_5529OAD VMD1HTE1A71_ns:.OAD2 MD ""AMS"" Node ""INGJJMGRJMTSNB0001AG2OLT001"" }","Fri 18 Oct 2013 05:01:46"

Сообщите мне то, что Вы думаете, или если у Вас есть проблемы, выполняющие его. Если это сделает то, в чем Вы нуждаетесь, то я заполню детали того, как это работает.

Ссылки

0
27.01.2020, 22:23
[116627] Ну, если у вас всегда одно и то же количество полей на запись и между записями ничего нет (предположения, которые я делаю на основании вашего поста, которые могут быть или не быть правильными), вы можете пойти по неуклюжему маршруту. Это сохранит порядок столбцов и встроенные новые строки. Предположим, что следующее находится в разделе [117058]. awk[117059]:

osascript -e 'tell application "System Events"' \
          -e 'keystroke "s" using {command down, option down}' \
          -e 'end tell'
Тогда вы можете просто вызвать его с помощью [117060]FieldsPerRecord[117061], установленного в командной строке:

Который выдаст следующие данные в CSV-кодировке, которые LibreOffice Calc, кажется, без проблем принимает:

Обратите внимание, что я использую подход [117062]цитирую все[117063], который, по крайней мере, для меня, производит меньше сюрпризов при импорте, но вы можете отключить это, установив [117064]Q = ""[117065], [117066]Sep = "","[117067] и две [117068]gsub()[117069] строки в [117070]sanitise()[117071]. Однако

[117073], я [117074] не[117075] думаю, что это проблема регекса. Эти данные имеют фиксированную ширину, поэтому кажется, что [117076]Perl's [117323]распаковка

- это, пожалуй, лучший подход. Я никогда не мог об этом задуматься, но для меня это может быть хорошей возможностью узнать, хочет ли кто-нибудь показать способ сделать это с помощью [117078]распаковки[117079].

update

I'm not a Perl Hacker™, но следующее, кажется, работает хорошо, не делает никаких предположений о содержании многострочных полей, сохраняет порядок полей и все оригинальные промежутки между полями (но убирает лидирующее пространство из заголовков), и кажется опасным для моих неподготовленных глаз:

Просто вызываю:

# build list of files; note, won't work when filename contains a space or colon
files=""
for i in `seq 30 99`; do
    files="$files my_log-bin.$i"
done

scp $files root@192.168.103.66:/backup/
Наверное, было бы лучше использовать [117080]Text::CSV[117081], но меня больше интересовало, как работает [117082]распаковка[117083]. Похоже, что для данных фиксированной ширины она гораздо более читабельная и надежная, чем регулярные выражения.[116644].
1
27.01.2020, 22:23

Теги

Похожие вопросы