我有一个带有身份证号码和一堆代表基因树的模式的文件
前任:

021557  (sfra,(pdep,snud),((spal,sint),(sdro,(hpul,(sprp,afra)))));
005852  (snud,sfra,(pdep,(hpul,((afra,sprp),(sint,(spal,sdro))))));
023685  (sfra,snud,(pdep,(hpul,((sprp,(afra,spal)),(sdro,sint)))));
022020  (sfra,snud,(pdep,(hpul,(afra,(sprp,(sdro,(sint,spal)))))));
028284  (sfra,snud,(pdep,(hpul,(sprp,((sdro,sint),(spal,afra))))));

我对某个姐妹分类单元分组(spal,afra)感兴趣。如果树包含(spal,afra),我想从另一列打印id。
如果仅在上面的数据上运行,则输出应为:
023685号
028284号
我要做的是:
awk '{if ($2 == "(spal,afra)") { print $1 } }'

但我意识到,我要匹配的部分是在一堆其他字符内,而且在任何可预测的位置…
所以我需要寻找
任意数量的小写字母或括号或逗号
(西班牙,非洲)
任何数量的小写字母或括号或逗号或;
另外,我想我想知道发生在另一个顺序(afra,spal)。但是我要运行单独的匹配,组合输出,如果我记得对的话,用sort和uniq-c做一些事情……我以后可能会自己想出来的。
我对这个有点陌生,我已经花了几个小时想办法解决问题。谢谢您!

最佳答案

你好像把它作为输入文件

$ cat file
021557  (sfra,(pdep,snud),((spal,sint),(sdro,(hpul,(sprp,afra)))));
005852  (snud,sfra,(pdep,(hpul,((afra,sprp),(sint,(spal,sdro))))));
023685  (sfra,snud,(pdep,(hpul,((sprp,(afra,spal)),(sdro,sint)))));
022020  (sfra,snud,(pdep,(hpul,(afra,(sprp,(sdro,(sint,spal)))))));
028284  (sfra,snud,(pdep,(hpul,(sprp,((sdro,sint),(spal,afra))))));

用锥子
要打印包含(spal,afra)的任何行的第一列:
$ awk '/[(]spal,afra[)]/{print $1}' file
028284

条件/[(]spal,afra[)]/选择包含(spal,afra)的行,并在这些行上打印第一个字段。
在awk正则表达式中,paren是活动字符。因为我们想匹配字面上的paren,所以我们把它们放在方括号中,比如print $1[(]
使用sed
$ sed -n '/(spal,afra)/ s/\t.*//p' file
028284

[)]不会打印任何内容,除非我们明确要求。sed -n选择包含/(spal,afra)/的行。(spal,afra)删除第一个选项卡后的所有内容,然后打印剩余内容。
默认情况下,sed使用基本正则表达式。这意味着s/\t.*//p(不活动。因此,我们不需要逃避他们。
使用grep和cut
$ grep '(spal,afra)' file | cut -f1
028284

)选择包含grep '(spal,afra)' file的行,并从这些行中选择第一个字段。
与sed一样,grep默认使用基本正则表达式。这意味着(spal,afra)cut -f1都被视为文本字符,不需要对它们进行转义。
备选方案:查找()
如果我们想在(spal,afra)之外查找(afra,spal),则需要更新正则表达式。以awk为例:
awk '/[(](spal,afra|afra,spal)[)]/{print $1}' file2
023685
028284

在这里,垂直条(afra,spal)分隔选项。regex接受酒吧之前或之后的内容。

07-26 09:38