0

我有两个制表符分隔的文件

file1.txt

field1
field2
field3

file2.txt

field1   value f11
field1   value f12
field1   value f13
field2   value f21
field2   value f22
field2   value f23
field3   value f31

我想要输出

field1   value f11, value f12 , valuef13
field2   value f21, value f22 , valuef23
field3   value f31

我正在尝试这个

awk -F"\t" 'NR==FNR{a[$1] = $1;next} { print a[$1]  }' file1.txt file2.txt

它空空如也

如果 filds 在 file1 中而不在 file2 中,那么应该是空白

更新:

这是我终端的输出

    ubuntu@ubuntu:/mnt/coding/awk$ cat f1.txt 
    field1
    field2
    field3
    field9

    ubuntu@ubuntu:/mnt/coding/awk$ cat f2.txt 
    field1  value f11
    field1  value f12
    field1  value f13
    field2  value f21
    field2  value f22
    field2  value f23
    field3  value f31

    ubuntu@ubuntu:/mnt/coding/awk$ awk -F"\t" 'NR==FNR{a[$1] = a[$1]", "$2;next}{gsub("^,","",a[$1]);print $1"\t"a[$1]}' f2.txt f1.txt
    field1  
    field2  
    field3  
    field9  

    ubuntu@ubuntu:/mnt/coding/awk$ awk --version
GNU Awk 3.1.8
Copyright (C) 1989, 1991-2010 Free Software Foundation.

更新 2:

ubuntu@ubuntu:/mnt/coding/awk$ od -xcb f1.txt
0000000    6966    6c65    3164    660a    6569    646c    0a32    6966
          f   i   e   l   d   1  \n   f   i   e   l   d   2  \n   f   i
        146 151 145 154 144 061 012 146 151 145 154 144 062 012 146 151
0000020    6c65    3364    660a    6569    646c    0a39    000a
          e   l   d   3  \n   f   i   e   l   d   9  \n  \n
        145 154 144 063 012 146 151 145 154 144 071 012 012
0000035
ubuntu@ubuntu:/mnt/coding/awk$ od -xcb f2.txt
0000000    6966    6c65    3164    2020    6176    756c    2065    3166
          f   i   e   l   d   1           v   a   l   u   e       f   1
        146 151 145 154 144 061 040 040 166 141 154 165 145 040 146 061
0000020    0a31    6966    6c65    3164    2020    6176    756c    2065
          1  \n   f   i   e   l   d   1           v   a   l   u   e    
        061 012 146 151 145 154 144 061 040 040 166 141 154 165 145 040
0000040    3166    0a32    6966    6c65    3164    2020    6176    756c
          f   1   2  \n   f   i   e   l   d   1           v   a   l   u
        146 061 062 012 146 151 145 154 144 061 040 040 166 141 154 165
0000060    2065    3166    0a33    6966    6c65    3264    2020    6176
          e       f   1   3  \n   f   i   e   l   d   2           v   a
        145 040 146 061 063 012 146 151 145 154 144 062 040 040 166 141
0000100    756c    2065    3266    0a31    6966    6c65    3264    2020
          l   u   e       f   2   1  \n   f   i   e   l   d   2        
        154 165 145 040 146 062 061 012 146 151 145 154 144 062 040 040
0000120    6176    756c    2065    3266    0a32    6966    6c65    3264
          v   a   l   u   e       f   2   2  \n   f   i   e   l   d   2
        166 141 154 165 145 040 146 062 062 012 146 151 145 154 144 062
0000140    2020    6176    756c    2065    3266    0a33    6966    6c65
                  v   a   l   u   e       f   2   3  \n   f   i   e   l
        040 040 166 141 154 165 145 040 146 062 063 012 146 151 145 154
0000160    3364    2020    6176    756c    2065    3366    0a31    000a
          d   3           v   a   l   u   e       f   3   1  \n  \n
        144 063 040 040 166 141 154 165 145 040 146 063 061 012 012
0000177
ubuntu@ubuntu:/mnt/coding/awk$ 

其他:

awk -F"\t" 'NR==FNR{a[$1] = a[$1]", "$2; print "["$1"/"$2"]"; next}{gsub("^,","",a[$1]);print $1"\t"a[$1]}' f2.txt f1.txt
[field1  value f11/]
[field1  value f12/]
[field1  value f13/]
[field2  value f21/]
[field2  value f22/]
[field2  value f23/]
[field3  value f31/]
[/]
field1  
field2  
field3  
field9  
4

2 回答 2

4

这是一种可能的解决方案:

NR==FNR{a[$1]=a[$1]", "$2;next}{gsub("^,","",a[$1]);print $1"\t"a[$1]}

这通过file2首先存储键和值,然后处理 file1 以输出它们来工作。以下(略微格式化的)成绩单显示了这一点:

pax> cat file1.txt

field1
field2
field3
field9

pax> cat file2.txt

field1  value f11
field1  value f12
field1  value f13
field2  value f21
field2  value f22
field2  value f23
field3  value f31

pax> awk -F"\t" 'NR == FNR{
...>                 a[$1] = a[$1]", "$2;
...>                 next
...>             }
...>             {
...>                 gsub ("^,", "", a[$1]);
...>                 print $1"\t"a[$1]
...>             }' file2.txt file1.txt 

field1   value f11, value f12, value f13
field2   value f21, value f22, value f23
field3   value f31
field9

根据我建议您使用sed命令的更新,print "["$1"/"$2"]"您得到:

[field1  value f11/]
[field1  value f12/]
[field1  value f13/]
[field2  value f21/]
[field2  value f22/]
[field2  value f23/]
[field3  value f31/]

这表明这些字段不是制表符分隔的。命令的输出也证实了这一点od,您可以清楚地看到2020两个空格序列。

您需要对其进行排序,否则命令将无法使用-F"\t". 例如,如果我file2.txt用空格替换 my 中的每个选项卡,我会看到您所看到的内容:

pax> awk -F"\t" 'NR==FNR{a[$1] = a[$1]", "$2;next}
...>   {gsub("^, ","",a[$1]);print $1"\t"a[$1]}' file2.txt file1.txt 
field1  
field2  
field3  
field9  

因此,您需要做出决定:

  • 修改文件,使其制表符分隔;或者
  • 修改awk选项以使用实际文件格式。

鉴于您在该行的其他地方有空格,第一个选项可能是最简单的。要修改文件以用制表符替换每一行的第一组空格,您可以使用:

sed 's/  */\t/' file2.txt >file2a.txt
mv file2a.txt file2.txt                 # once you're happy.

(或使用-iGNU 的就地编辑选项sed)。

于 2013-03-20T03:18:30.333 回答
0

使用其他工具而不是 awk(并假设有一个选项卡可以将字段与 file2 中的值分开):

for f in `cat /tmp/file1.txt`; do grep $f /tmp/file2.txt | cut -f2- | paste -s -d, | sed "s/^/$f\t/g" ; done

(我会将此作为评论发布,但似乎无法避免评论中的反引号)

于 2013-03-20T03:50:10.723 回答