我想从这种格式转换文件
1;a;34;34;a
1;a;34;23;d
1;a;34;23;v
1;a;4;2;r
1;a;3;2;d
2;f;54;3;f
2;f;34;23;e
2;f;23;5;d
2;f;23;23;g
3;t;26;67;t
3;t;34;45;v
3;t;25;34;h
3;t;34;23;u
3;t;34;34;z
这种格式
1;a;34;34;a;34;23;d;34;23;v;4;2;r;3;2;d
2;f;54;3;f;34;23;e;23;5;d;23;23;g;;;
3;t;26;67;t;34;45;v;25;34;h;34;23;u;34;34;z
这些是cvs文件,所以它应该与awk或sed一起工作......但是到现在为止我都失败了。如果第一个值相同,我想将最后三个值添加到第一行。这将一直运行到文件中的最后一个条目。
这里有一些awk中的代码,但它不起作用:
#!/usr/bin/awk -f
BEGIN{ FS = " *; *"}
{ ORS = "\;" }
{
x = $1
print $0
}
{ if (x == $1)
print $3, $4, $5
else
print "\n"
}
END{
print "\n"
}
答案 0 :(得分:2)
$ cat tst.awk
BEGIN { FS=OFS=";" }
{ curr = $1 FS $2 }
curr == prev {
sub(/^[^;]*;[^;]*/,"")
printf "%s", $0
next
}
{
printf "%s%s", (NR>1?ORS:""), $0
prev = curr
}
END { print "" }
$ awk -f tst.awk file
1;a;34;34;a;34;23;d;34;23;v;4;2;r;3;2;d
2;f;54;3;f;34;23;e;23;5;d;23;23;g
3;t;26;67;t;34;45;v;25;34;h;34;23;u;34;34;z
答案 1 :(得分:1)
如果我理解你是否想要从具有相同前两个字段的所有行的字段3-5(前面有这两个字段)构建一行,那么
awk -F \; 'key != $1 FS $2 { if(NR != 1) print line; key = $1 FS $2; line = key } { line = line FS $3 FS $4 FS $5 } END { print line }' filename
那是
key != $1 FS $2 { # if the key (first two fields) changed
if(NR != 1) print line; # print the line (except at the very
# beginning, to not get an empty line there)
key = $1 FS $2 # remember the new key
line = key # and start building the next line
}
{
line = line FS $3 FS $4 FS $5 # take the value fields from each line
}
END { # and at the very end,
print line # print the last line (that the block above
} # cannot handle)
答案 2 :(得分:1)
你在awk
得到了很好的答案。这是perl
中的一个:
perl -F';' -lane'
$key = join ";", @F[0..1]; # Establish your key
$seen{$key}++ or push @rec, $key; # Remember the order
push @{ $h{$key} }, @F[2..$#F] # Build your data structure
}{
$, = ";"; # Set the output list separator
print $_, @{ $h{$_} } for @rec' file # Print as per order
答案 3 :(得分:0)
这似乎比其他答案复杂得多,但它增加了一些东西:
for(key in array)
语法时对键进行编号,mac上的posix awk也不会保持数组元素的顺序。为了保持输出顺序,您可以像我一样跟踪它,或者随后进行排序。输出中具有匹配的字段数似乎是每个指定输出的要求。在不知道它应该是什么的情况下,这个awk脚本被构建为首先加载所有行,计算输出行中的最大字段数,然后按行顺序输出行。
#!/usr/bin/awk -f
BEGIN {FS=OFS=";"}
{
key = $1
# create an order array for the mac's version of awk
if( key != last_key ) {
order[++key_cnt] = key
last_key = key
}
val = a[key]
# build up an output line in array a for the given key
start = (val=="" ? $1 OFS $2 : val)
a[key] = start OFS $3 OFS $4 OFS $5
# count number of fields for each built up output line
nf_a[key] += 3
}
END {
# compute the max number of fields per any built up output line
for(k in nf_a) {
nf_max = (nf_a[k]>nf_max ? nf_a[k] : nf_max)
}
for(i=1; i<=key_cnt; i++) {
key = order[i]
# compute the number of blank flds necessary
nf_pad = nf_max - nf_a[key]
blank_flds = nf_pad!=0 ? sprintf( "%*s", nf_pad, OFS ) : ""
gsub( / /, OFS, blank_flds )
# output lines along with appended blank fields in order
print a[key] blank_flds
}
}
如果提前知道输出行中所需的字段数,只需在键开关上附加空白字段,而不是所有这些数组都可以工作并制作更简单的脚本。
我得到以下输出:
1;a;34;34;a;34;23;d;34;23;v;4;2;r;3;2;d
2;f;54;3;f;34;23;e;23;5;d;23;23;g;;;
3;t;26;67;t;34;45;v;25;34;h;34;23;u;34;34;z