我有这样的档案:
AA,A=14,B=356,C=845,D=4516
BB,A=65,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,F=225我从来不知道在行中是否遗漏了A,B,C或D值。但我需要转换这个文件如下:
AA,A=14,B=356,C=845,D=4516,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,-,-,F=225因此,如果有任何值丢失,只需打印-标记。我的计划是拥有相同数量的列以便于解析。我更喜欢awk解决方案。谢谢你的建议或帮助。
我的第一次尝试是:
awk '{gsub(/[,]/, "\t")}; BEGIN{ FS = OFS = "\t" } { for(i=1; i<=NF; i++) if($i ~ /^ *$/) $i = "-" }; {print $0}'但我注意到,有些价值观缺失了。
编辑:
从我的头上我知道有值A,B,C,D,E,F.
发布于 2016-09-05 15:15:40
$ cat file.txt
AA,A=14,B=356,C=845,D=4516
BB,A=65,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,F=225
$ perl -F, -le '@k=(A..F);
$op[0]=$F[0]; @op[1..6]=("-")x6;
$j=0; for($i=1;$i<=$#F;){ if($F[$i] =~ m/$k[$j++]=/){$op[$j]=$F[$i]; $i++} }
print join(",",@op)
' file.txt
AA,A=14,B=356,C=845,D=4516,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428
CC,A=88,B=54,C=549,-,-,F=225-F,在,上拆分输入行并保存到@F数组-l从输入行中删除换行符,将换行符添加到输出@k=(A..F);用A、B等对@k数组进行初始化,直至F$op[0]=$F[0]; @op[1..6]=("-")x6;使用@F的第一个元素和剩下的6个元素作为-来初始化@op数组@F数组,如果元素与相应索引中的@k数组元素匹配,则更改@op元素。print join(",",@op)打印以,为分隔符的@op数组发布于 2016-09-05 15:15:50
Perl来救我!
您还没有指定如何获取标头信息,因此在下面的脚本中,@header数组将直接填充。
%to_idx散列将列名映射到它们的索引(A => 0、B => 1等)。
每一行被分割成字段,每个字段与预期的字段($next)进行比较,并在需要时打印破折号。对于缺失的拖尾字段,情况也是如此。
#!/usr/bin/perl
use warnings;
use strict;
my @header = qw( A B C D E F );
my %to_idx = map +($header[$_] => $_), 0 .. $#header;
open my $IN, '<', shift or die $!;
while (<$IN>) {
chomp;
my @fields = split /,/;
print shift @fields;
my $next = 0;
for my $field (@fields) {
my ($name, $value) = split /=/, $field;
print ',-' x ($to_idx{$name} - $next);
print ",$name=$value";
$next = $to_idx{$name} + 1;
}
print ',-' x (1 + $#header - $next); # Missing trailing fields.
print "\n"
}发布于 2016-09-06 13:08:21
BEGIN {
PROCINFO["sorted_in"]="@ind_str_asc" # order for for(i in a)
for(i=65;i<=90;i++) # create the whole alphabet to array a[]
a[sprintf("%c", i)] # you could read the header and use that as well
}
{
split($0,b,",") # split record by ","
printf "%s", b[1] # printf first element (AA, BB...)
delete b[1] # get rid of it
for(i in b)
b[substr(b[i],1,1)]=b[i] # take the first letter to use as index (A=12)
for(i in a) # go thru alphabet and printf from b[]
printf "%s%s", OFS, (i in b?b[i]:"-"); print ""
}
awk -v OFS=\, -f parsing.awk tbparsed.txt
AA,A=14,B=356,C=845,D=4516,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-
BB,A=65,-,C=255,D=841,E=5133,F=1428,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-
CC,A=88,B=54,C=549,-,-,F=225,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-它为记录中没有找到的每一个字母打印"-“。如果数据有头部,可以将split转换为二维数组b[NR],并将for(i in a)更改为for(i in b[1]) ... printf ... b[NR][b[1][i]] ...,如果不需要静态第一列,则删除第一个printf和delete。
https://stackoverflow.com/questions/39331907
复制相似问题