我想从unix中的文本文件中过滤数据。 我在unix中有如下文本文件:
A 200
B 300
C 400
A 100
B 600
B 700
我如何根据上面的awk中的数据修改/创建数据?
A 200 100
B 300 600 700
C 400
我在awk中并不是那么好,我相信awk / perl最适合这个。
答案 0 :(得分:3)
awk 'END {
for (R in r)
print R, r[R]
}
{
r[$1] = $1 in r ? r[$1] OFS $2 : $2
}' infile
如果第一个字段中值的顺序很重要, 将需要更多代码。 解决方案取决于您的 awk 实现和版本。
说明:
r[$1] = $1 in r ? r[$1] OFS $2 : $2
将数组r元素$ 1的值设置为:
表达?如果为true:如果为false则为三元运算符。 有关详情,请参阅ternary operation。
答案 1 :(得分:2)
你可以这样做,但是使用Perl总是有不止一种方法可以做到这一点:
my %hash;
while(<>) {
my($letter, $int) = split(" ");
push @{ $hash{$letter} }, $int;
}
for my $key (sort keys %hash) {
print "$key " . join(" ", @{ $hash{$key} }) . "\n";
}
应该这样工作:
$ cat data.txt | perl script.pl
A 200 100
B 300 600 700
C 400
答案 2 :(得分:1)
不是特定于语言的。更像是伪代码,但这里的想法是:
- Get all lines in an array
- Set a target dictionary of arrays
- Go through the array :
- Split the string using ' '(space) as the delimiter, into array parts
- If there is already a dictionary entry for `parts[0]` (e.g. 'A').
If not create it.
- Add `parts[1]` (e.g. 100) to `dictionary(parts[0])`
就是这样! : - )
我会这样做,可能是在Python中,但这只是一种品味问题。
答案 3 :(得分:0)
使用awk
,对其中的输出进行排序:
awk '
{ data[$1] = (data[$1] ? data[$1] " " : "") $2 }
END {
for (i in data) {
idx[++j] = i
}
n = asort(idx);
for ( i=1; i<=n; i++ ) {
print idx[i] " " data[idx[i]]
}
}
' infile
使用外部程序sort
:
awk '
{ data[$1] = (data[$1] ? data[$1] " " : "") $2 }
END {
for (i in data) {
print i " " data[i]
}
}
' infile | sort
对于这两个命令,输出是:
A 200 100
B 300 600 700
C 400
答案 4 :(得分:0)
使用sed
:
script.sed
的内容:
## First line. Newline will separate data, so add it after the content.
## Save it in 'hold space' and read next one.
1 {
s/$/\n/
h
b
}
## Append content of 'hold space' to current line.
G
## Search if first char (\1) in line was saved in 'hold space' (\4) and add
## the number (\2) after it.
s/^\(.\)\( *[0-9]\+\)\n\(.*\)\(\1[^\n]*\)/\3\4\2/
## If last substitution succeed, goto label 'a'.
ta
## Here last substitution failed, so it is the first appearance of the
## letter, add it at the end of the content.
s/^\([^\n]*\n\)\(.*\)$/\2\1/
## Label 'a'.
:a
## Save content to 'hold space'.
h
## In last line, get content of 'hold space', remove last newline and print.
$ {
x
s/\n*$//
p
}
像以下一样运行:
sed -nf script.sed infile
结果:
A 200 100
B 300 600 700
C 400
答案 5 :(得分:0)
这可能对您有用:
sort -sk1,1 file | sed ':a;$!N;s/^\([^ ]*\)\( .*\)\n\1/\1\2/;ta;P;D'
A 200 100
B 300 600 700
C 400