如何在Linux中使用单行Perl命令将数据转换为列并创建CSV文件

时间:2019-07-10 10:27:40

标签: linux perl

我有这样的文本文件

Name : Harsha
Class : 12
Hobby : dance 
Name : Nikhil
Class : 11
Hobby : sing
Name : akhil
Class :10
Hobby : Gym

如何使用name创建包含三列的classhobbyPerl -0pe command one-liner CSV文件。

3 个答案:

答案 0 :(得分:1)

这里是一个例子:

perl -F'/\s*:\s*/' -E'
    chomp $F[1]; 
    /^Name/ && push @name, $F[1];
    /^Class/ && push @class, $F[1];
    /^Hobby/ && push @hobby, $F[1];
    END {say join ",", $name[$_], $class[$_], $hobby[$_] for 0..$#name}
' input.txt

或者:

perl -nE '
    ($_, $v) = /^(\S+)\s*:\s*(\S+)/;
    /Name/ && push @name, $v;
    /Class/ && push @class, $v;
    /Hobby/ && push @hobby, $v; 
    END {say join ",", $name[$_], $class[$_], $hobby[$_] for 0..$#name}
' input.txt

输出

Harsha,12,dance 
Nikhil,11,sing
akhil,10,Gym

答案 1 :(得分:1)

要求提供-0pe

perl -0pe 's/^Hobby *: *//mg; s/^(.+?) *: *(.+)\n/$2,/mg'

说明:

由于-0,所有输入都被“吸引”到$_中。那么正则表达式在做什么?

  1. s/^Hobby *: *//mg;这将仅删除“标签” Hobby以及以下冒号和空格。
  2. s/^(.+?) *: *(.+)\n/$2,/mg,这将删除所有其他“标签”及其冒号和可能的空格,(.+?) *: *。然后它将记住(.+)之后的所有文本,并删除结尾的行尾。它将替换为找到的文本和逗号。

因此,实质上,我要删除所有标签和行尾。除“ Hobby”行(条目的最后一行)外,所有行尾均用逗号替换。换行符保留在这里。

当然,到目前为止,这还不是万无一失的,但我认为这足以让您考虑,因为您没有表现出自行解决问题的任何尝试,所以我不想用最复杂的脚本让您不知所措这样也可以处理输入数据中的错误序列,丢失的数据或包含其他冒号的数据。

那是锻炼的机会。

玩得开心...

答案 2 :(得分:0)

使用库创建CSV文件总是更好,这样当遇到极端情况时,您就不会创建损坏的CSV或以错误的数据结尾。 Text::CSV中的csv函数非常适合oneliners。

perl -CS -MText::CSV=csv -ne'chomp; my ($n, $v) = split /\s*:\s*/, $_, 2;
  $row{$n} = $v; if ($n eq "Hobby") { push @rows, {%row}; %row = () }
  END { csv(in => \@rows, out => \*STDOUT, headers => [qw(Name Class Hobby)],
    auto_diag => 2) }' input.txt