通过awk或sed按第一列连接行


12

awk在以下情况下如何使用?

我想连接以同一列开头的行。只有在加入第一列保持(在这种情况下aaawwwhhh)。

文件可以用空格或制表符分隔。

输入示例:

aaa bbb ccc ddd NULL NULL NULL
aaa NULL NULL NULL NULL NULL NULL
aaa bbb ccc NULL NULL NULL NULL
www yyy hhh NULL NULL NULL NULL
hhh 111 333 yyy ooo hyy uuuioooy
hhh 111 333 yyy ooo hyy NULL

所需的输出:

aaa bbb ccc ddd NULL NULL NULL NULL NULL NULL NULL NULL NULL bbb ccc NULL NULL NULL NULL
www yyy hhh NULL NULL NULL NULL
hhh 111 333 yyy ooo hyy uuuioooy 111 333 yyy ooo hyy NULL

这样做的背景是,我想建立一个非常简单的基于文件的数据库,其中第一列始终是实体的标识符。基于同一标识符列的所有行都是串联的。


1
去了哪uuu线来自(输出)?
2012年

对不起这是我的错。我将对其进行编辑。
2012年

Answers:


8

要使用awk获取每一行的第一列,您可以执行以下操作:

< testfile awk '{print $1}'
aaa
aaa
aaa
www
hhh
hhh

这些是其余各行的键。因此,您可以使用第一列作为键,并将该行的第二列作为值来创建哈希表:

< testfile awk '{table[$1]=table[$1] $2;} END {for (key in table) print key " => " table[key];}'
www => yyy
aaa => bbbNULLbbb
hhh => 111111

为了获得整行的内容,从第2列开始,您需要收集所有列:

< testfile awk '{line="";for (i = 2; i <= NF; i++) line = line $i " "; table[$1]=table[$1] line;} END {for (key in table) print key " => " table[key];}'
www => yyy hhh NULL NULL NULL NULL 
aaa => bbb ccc ddd NULL NULL NULL NULL NULL NULL NULL NULL NULL bbb ccc    NULL NULL NULL NULL 
hhh => 111 333 yyy ooo hyy uuuioooy 111 333 yyy ooo hyy NULL 

嗨,是的,确实需要对哈希表进行细分。谢谢!
微小的

2
@tiny-我假设需要保留顺序。是不是这样(此答案产生的排序与哈希机制相对应,而不是您的原始订单)?
ire_and_curses 2012年

3

其他人可以用awk或sed回答,但是Python版本很简单,可能对您有所帮助。

#!/usr/bin/env python

input_file = 'input.dat'
in_fh      = open(input_file, 'r')

input_order = []
seen        = {}
for line in in_fh:    
    # Remove the newline character...
    line = line[:-1]

    # Separate the first column from the rest of the line...
    key_col, sep, rest_of_line = line.partition(" ")
    rest_of_line = sep + rest_of_line  

    # If we've seen this key already, concatenate the line...
    if key_col in seen:
        seen[key_col] += rest_of_line
    # ...otherwise, record the ordering, and store the new info
    else:
        input_order.append(key_col)
        seen[key_col] = rest_of_line

in_fh.close()

# Dump the ordered output to stdout
for unique_col in input_order:
    print unique_col + seen[unique_col]

很酷。以我的经验为零的python我甚至设法编辑脚本,它需要第一个参数为输入文件名:
微小的

2

这更像是coreutils的一个有趣的应用程序,我怀疑它在输入大时效率不高,因为它会为输入中的每一行调用join。

touch outfile
while read; do
  join -a1 -a2 outfile <(echo $REPLY) > tmp
  mv tmp outfile
done < infile

为了提高它的效率,节约outfiletmp一个RAMDISK可能的帮助。

编辑

或没有临时文件:

out=""
while read; do
  out=$(join -a1 -a2 <(echo -n "$out") <(echo -n "$REPLY"))
done < infile

echo "$out"

2

这是PERL的一线:

$ perl -e 'my %h; while(<>){chomp; @a=split(/\s+/); $k=shift(@a); $h{$k}.=join(" ", @a) . " "; } map{$h{$_}=~s/\s*$//; print "$_ $h{$_}\n}keys(%hash);' infile
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.