2014-08-27 57 views
1

假设FILE.TXT象下面这样:找到了多条线路共同的元素在文本文件中

A1 B C D 
E F C H 
C J 
A2 F B 
D J C 
F T Y U I 
B C N J Y 

我需要的是来检查开始的行模式“^ A”,然后查找后的元素(从$ 2到行尾)。然后我需要从这些元素开始寻找行中的常见元素。这里是输出FILE.TXT:

A1 C J 
A2 Y 

A1 J C 
A2 Y 

在输出共同的元件(例如J和C)的顺序并不重要。

P.S. Awk是首选。

+2

不清楚你的意思。另外,你到目前为止做了什么?到目前为止,有[awk中的问题数量](http://stackoverflow.com/search?q=user%3A3684042+ [awk]),您应该知道如何从以下开始:) – fedorqui 2014-08-27 15:26:37

+1

对于每个'A *'行想要打印出每一行的行内容之间通用的所有元素,这些元素的起始元素等于所讨论的'A *'行的元素? – 2014-08-27 15:26:52

+0

@EtanReisner:的确如此。 – user3684042 2014-08-27 15:28:53

回答

3

利用GNU AWK为真实二维阵列和删除阵列和长度(数组):

$ cat tst.awk 
{ for (i=1;i<=NF;i++) children[$1][$i] } 
/^A/{ parents[$1]; delete children[$1][$1] } 
END { 
    for (parent in parents) { 
     delete count 
     printf "%s", parent 
     for (child in children[parent]) 
      for (grandchild in children[child]) 
       if (++count[grandchild] == length(children[parent])) 
        printf " %s", grandchild 
     print "" 
    } 
} 

$ awk -f tst.awk file 
A1 C J 
A2 Y 

它通过只检查该计数任何字段的出现在非数A行匹配A行中第2 +个字段的计数,因为它表示它在每种情况下都会发生。

+0

如果我想从其他文件中获取孙子们该怎么办?我的意思是,如果我们从file1中记录父母和他们的孩子,然后在fileB中寻找孙子女,该怎么办?我已经尝试通过将FNR == NR添加到第一行来修改您的代码,并且“; next;”在第二行“孩子[$ 1] [$ 1]”之后。我还在“END”之前添加了“{for(i = 1; i <= NF; i ++)Allchildren [$ 1] [$ i]}”,并且修改了第8和9行,如“for(forch(Allchildren [child]和“if(++ count [grandchild] == length(Allchildren [parent]))”。你能让我知道我做错了什么吗? – user3684042 2014-08-28 13:52:25

+1

不要改变它的工作原样,因为该脚本中没有任何内容关心您拥有多少独立的输入文件。只需将你喜欢的任何文件添加到arg列表awk -f tst.awk file1 file2 file3 ...中。如果这不起作用,那么更新您的问题以显示一些示例输入和预期输出并澄清您的新要求。 – 2014-08-28 15:01:02

+1

@ Ed Morton:非常感谢。我可以编辑你的程序来调整我的问题的需求。感谢您的关注。在学习awk时,你的编程风格是一个很好的示例。 – user3684042 2014-08-28 15:20:09

1

这有点难看,我觉得应该以更清晰的方式进行操作,但至少对样本数据有效。

/^A/ { 
    amap[$1]=NF - 1 
    for (i=2; i<=NF; i++) { 
     rmap[$i]=rmap[$i] (rmap[$i]?SUBSEP:"") $1 
    } 
    next 
} 

$1 in rmap { 
    split(rmap[$1], a, SUBSEP) 
    for (f in a) { 
     for (i=1; i<=NF; i++) { 
      afmap[a[f],$i]++ 
     } 
    } 
} 

END { 
    for (af in afmap) { 
     split(af, a, SUBSEP) 
     if (afmap[af] == amap[a[1]]) { 
      o[a[1]]=o[a[1]] (o[a[1]]?" ":"") a[2] 
     } 
    } 
    for (f in o) { 
     print f, o[f] 
    } 
}