我有这样的文本文件
Name : Harsha
Class : 12
Hobby : dance
Name : Nikhil
Class : 11
Hobby : sing
Name : akhil
Class :10
Hobby : Gym
如何使用name
创建包含三列的class
,hobby
和Perl -0pe command one-liner
CSV文件。
答案 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
,所有输入都被“吸引”到$_
中。那么正则表达式在做什么?
s/^Hobby *: *//mg;
这将仅删除“标签” Hobby
以及以下冒号和空格。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