我有一个CSV文件,它被转换成.DAT,我有一个AWK文件,它假设要做DAT文件的映射。AWK文件中的代码如下所示。
DAT文件的内容如下(分隔的选项卡):
ODT AGE CDT CO SEX TIME VALUE COMMENT
P3 Y6-8 ACT FG F 2011 1297
P4 Y3-4 EMP FG M 2011 6940 b
P1 Y7-9 GRT FG F 2011 0 c我要做的是:
下面是我的代码,它只修复了第一点
BEGIN {
FS = "," ;
OFS = " " ;
}
{
if(NR == 1)
{
split($0, tmp, ",");
for(i = 1; i <= NF; i++)
fields[tmp[i]] = i
print tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8]
else
{
split($0, tmp, ",");
for(i = 1; i <= NF; i++)
fields[tmp[i]] = i
print tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8]
}
}dat文件中的预期结果:
ODT AGE CDT CO SEX TIME NUMB STRING_COM STRING_STATUS
P3 Y6-8 ACT FG F 2011 1297
P4 Y3-4 ERT FG M 2011 6940 b
P1 Y7-9 GRT FG F 2011 0 c在CSV文件中,分隔符是",“但是dat文件必须带有制表符分隔符,这就是为什么我有代码....FS=的原因,”关于第三点,解释是:我可能会收到其他不需要的列。因此,最后,我必须以某种方式指定只需要这些列: ODT、年龄、CDT、性别、时间、值、注释),其他任何收到的列都必须被忽略。
CSV文件是:
ODT,AGE,CDT,CO,SEX,TIME,VALUE,COMMENT
P3,Y6-8,ACT,FG,F,2011,1297,
P4,Y3-3,EMP,FG,M,2011,6940,b
P1,Y7-9,GRT,FG,F,2011,0,c下面提供的解决方案运行良好。还有一些问题:
如果我将列注释放在AGE或CDT之后,则在第二行中添加"c“字符。第二行包含两个制表符,然后是"c“字符。如果注释位于末尾,并包含字符"c",则"bcc“结果将仅在STRING_STATUS上显示,而不是执行分隔> "c”转到STRING_COM,而"bcc“则指向STRING_STATUS。
必须实施以下情况:
我该怎么做?
有人能在这个问题上提供帮助吗?
发布于 2014-04-22 19:15:53
如果所有行都有相同的列顺序:
awk '
BEGIN {
FS=","; OFS="\t";
a["ODT"]=1;a["AGE"]=1;a["CDT"]=1;a["CO"]=1;
a["SEX"]=1;a["TIME"]=1;a["VALUE"]=1;a["COMMENT"]=1;
}
NR==1 {
$NF=substr($NF,1,length($NF)-1);
for(i=1;i<=NF;i++) if($i in a) a[$i]=i;
}
{ print $a["ODT"],$a["AGE"],$a["CDT"],$a["CO"],$a["SEX"],$a["TIME"],NR==1?"NUMB":$a["VALUE"],
NR==1?"STRING_COM"OFS"STRING_STATUS":($a["COMMENT"]!="c"?""OFS$a["COMMENT"]:$a["COMMENT"]);
}' input.txt我稍微更改了输入,添加了一个列(ADDED),并重新排序了另外两个列(TIME和VALUE):
ODT,ADDED,AGE,CDT,CO,SEX,VALUE,TIME,COMMENT
P3,111,Y6-8,ACT,FG,F,1297,2011,
P4,222,Y3-3,EMP,FG,M,6940,2011,b
P1,333,Y7-9,GRT,FG,F,0,2011,c输出:
ODT AGE CDT CO SEX TIME NUMB STRING_COM STRING_STATUS
P3 Y6-8 ACT FG F 2011 1297
P4 Y3-3 EMP FG M 2011 6940 b
P1 Y7-9 GRT FG F 2011 0 c编辑
如果输入的列比需要的多,那么额外的列将不会出现在输出中,例如,我在这里使用的输入有一个额外的列ADDED,而在输出中没有出现。
它将按所述首选的顺序打印输出,即ODT AGE CDT CO SEX TIME NUMB STRING_COM STRING_STATUS,而不管它们在输入中出现的顺序如何。同样,在我使用的输入中,列VALUE前面出现了TIME,但在输出中,TIME是第一位,NUMB是第二位。通过
如果所有行都有相同的列顺序
我的意思是,如果所有行都遵循标题行的顺序。如果标头中的顺序是ODT AGE CDT CO SEX TIME VALUE COMMENT,那么所有行中的数据都按照这个顺序显示,如果标头中的顺序是AGE ODT CDT CO SEX TIME VALUE COMMENT,那么所有其他行中的数据都有这个顺序。它并不假设ODT总是所有文件中的第一列,而是假设在文件中顺序是由头定义的。如果不是这样的话,代码就无法工作。
EDIT2
我用以下方法进行了测试:
ODT,ADDED,AGE,CDT,CO,SEX,VALUE,TIME,COMMENT
P3,111,Y6-8,ACT,FG,F,1297,2011,cd
P4,222,Y3-3,EMP,FG,M,6940,2011,bd
P1,333,Y7-9,GRT,FG,F,0,2011,c作为输入文件和输出是:
ODT AGE CDT CO SEX TIME NUMB STRING_COM STRING_STATUS
P3 Y6-8 ACT FG F 2011 1297 cd
P4 Y3-3 EMP FG M 2011 6940 bd
P1 Y7-9 GRT FG F 2011 0 cbd和cd在STRING_COM列下,原因是标题比通常为8个字符的制表符长。输出是分开的,可以打印两个制表符以使它们在STRING_STATUS下出现,但如果输出要由另一个程序使用,则可能会导致一些问题,因为它会生成一个空字段。如果仅用于打印,则可以将行号12改为:
NR==1?"STRING_COM"OFS"STRING_STATUS":($a["COMMENT"]!="c"?""OFS""OFS$a["COMMENT"]:$a["COMMENT"]);产出如下:
ODT AGE CDT CO SEX TIME NUMB STRING_COM STRING_STATUS
P3 Y6-8 ACT FG F 2011 1297 cd
P4 Y3-3 EMP FG M 2011 6940 bd
P1 Y7-9 GRT FG F 2011 0 c发布于 2014-05-29 00:26:42
我以Ashkan的答案作为起点,并给出了下面的脚本。但是,这两点在CSV文件的上下文中没有意义,除非值被引号(或其他东西)包围。请澄清。
Awk脚本:
BEGIN {
FS=","; OFS="\t";
a["ODT"]=1;a["AGE"]=1;a["CDT"]=1;a["CO"]=1;
a["SEX"]=1;a["TIME"]=1;a["VALUE"]=1;a["COMMENT"]=1;
}
NR==1 {
for (i=1;i<=NF;i++) {
if ($i in a) a[$i]=i;
}
print "ODT","AGE","CDT","CO","SEX","TIME","NUMB","STRING_COM","STRING_STATUS"
}
NR!=1{
split($0,line,/,/);
value = line[a["VALUE"]];
comment = line[a["COMMENT"]];
string_com="";
string_status="";
if (value==":") {
value="";
if (comment=="c") string_com = "c";
if (comment=="u") string_status = "u";
if (comment=="cd") string_com = "c";
if (comment=="bc") {
string_com = "c";
string_status = "b";
}
}
else {
if (comment=="c")
string_com = "c";
else if (comment=="d") {
# convert value
string_com = "";
string_status = "";
}
else if (comment=="du") {
# convert value
string_status = "";
}
else
string_status = comment;
}
print line[a["ODT"]],
line[a["AGE"]],
line[a["CDT"]],
line[a["CO"]],
line[a["SEX"]],
line[a["TIME"]],
value,
string_com,
string_status
}https://stackoverflow.com/questions/23221837
复制相似问题