linux - 根据标题类别将行转换为属于不同类别的相应列

标签 linux unix awk sed rows

我有这样的输入文件,其中 KO id 像 K00001 ,K00002 K00006 等特定类别下的 01100metabolicpathway , 01523Antifolateresistance(7), 01522Endocrineresistance(7)

01100Metabolicpathways(812)
K00001
Ca_19344,Ca_19730
K00002
Ca_09433,Ca_23715,Ca_15858,Ca_19929,Ca_26670
K00008
Ca_20904
K00011
Ca_15431
K00012
Ca_10466,Ca_23867,Ca_06574
K00013
Ca_08009
K00016
Ca_02357,Ca_16304
K00020
Ca_08005
K00021
Ca_10251,Ca_09868
01523Antifolateresistance(7)
K00297
Ca_26773
K00600
Ca_00054,Ca_00455,Ca_14951,Ca_11397,Ca_08538,Ca_11540,Ca_11173
01522Endocrineresistance(7)
K04650
Ca_20380,Ca_04277

期望的输出是这样的:

K00001  Ca_19344,Ca_19730   01100Metabolicpathways(812)
K00002  Ca_09433,Ca_23715,Ca_15858,Ca_19929,Ca_26670    01100Metabolicpathways(812)
K00006  Ca_14695,Ca_21671,Ca_07219,Ca_24024,Ca_23566,Ca_27084   01100Metabolicpathways(812)
K00008  Ca_20904    01100Metabolicpathways(812)
K00011  Ca_15431    01100Metabolicpathways(812)
K00012  Ca_10466,Ca_23867,Ca_06574  01100Metabolicpathways(812)
K00013  Ca_08009    01100Metabolicpathways(812)
K00016  Ca_02357,Ca_16304   01100Metabolicpathways(812)
K00020  Ca_08005    01100Metabolicpathways(812)
K00021  Ca_10251,Ca_09868   01100Metabolicpathways(812)
K00297  Ca_26773    01523Antifolateresistance(7)
K00600  Ca_00054,Ca_00455,Ca_14951,Ca_11397,Ca_08538,Ca_11540,Ca_11173  01523Antifolateresistance(7)    
K04650  Ca_20380,Ca_04277   01522Endocrineresistance(7)

我通过将 KO id 取出到 KO_list.txt 文件中写了这样的东西,

K00001
K00002
K00006
K00008
K00011
K00012
K00013
K00016
K00020
K00021
for n in `cat KO_list.txt`
do
x=$(cat $2 | grep  -w -A1 "^$n"  | head -2 | sed ':a;N;$!ba;s/\n/\t/g')
echo -e "$x" | awk 'NF' >> output.txt
done

但它只给我这样的输出

K00001  Ca_19344,Ca_19730   
K00002  Ca_09433,Ca_23715,Ca_15858,Ca_19929,Ca_26670    
K00006  Ca_14695,Ca_21671,Ca_07219,Ca_24024,Ca_23566,Ca_27084   
K00008  Ca_20904    
K00011  Ca_15431    
K00012  Ca_10466,Ca_23867,Ca_06574  
K00013  Ca_08009    
K00016  Ca_02357,Ca_16304   
K00020  Ca_08005
K00021  Ca_10251,Ca_09868   
K00297  Ca_26773    
K00600  Ca_00054,Ca_00455,Ca_14951,Ca_11397,Ca_08538,Ca_11540,Ca_11173  
K04650  Ca_20380,Ca_04277

大家帮忙

######### 第二部分

谢谢大家,我真的很感谢你们所有有值(value)的评论,它还有第二部分是否有任何方法可以根据 Ca-ids 进行输出,其中 Ca-ids 位于第一列并且分别具有每个 Ca-ids 的信息而不是直接来自输入文件或来自所需输出文件(其中 KO-id 位于第一列)的 KO-id,我正在从任何同一文件中寻找这样的输出。

来自这个输入文件

01100Metabolicpathways(812)
K00001
Ca_19344,Ca_19730
01522Endocrineresistance(7)
K04650
Ca_20380,Ca_04277

或从输入文件创建的输出文件

K00001  Ca_19344,Ca_19730   01100Metabolicpathways(812)
K04650  Ca_20380,Ca_04277   01522Endocrineresistance(7)

新的期望输出应该是这样的

Ca_19344    K00001  01100Metabolicpathways(812)
Ca_19730    K00001  01100Metabolicpathways(812)
Ca_20380    K04650  01522Endocrineresistance(7)
Ca_04277    K04650  01522Endocrineresistance(7)

提前致谢

最佳答案

这是一个廉价的解决方案,但它适用于您的输入:

awk '/^[0-9].*/{ h = $0; next }/^K/{ k = $0; next }{ print k, $0, h }' yourfile

输出:

K00001 Ca_19344,Ca_19730 01100Metabolicpathways(812)
K00002 Ca_09433,Ca_23715,Ca_15858,Ca_19929,Ca_26670 01100Metabolicpathways(812)
K00008 Ca_20904 01100Metabolicpathways(812)
K00011 Ca_15431 01100Metabolicpathways(812)
K00012 Ca_10466,Ca_23867,Ca_06574 01100Metabolicpathways(812)
K00013 Ca_08009 01100Metabolicpathways(812)
K00016 Ca_02357,Ca_16304 01100Metabolicpathways(812)
K00020 Ca_08005 01100Metabolicpathways(812)
K00021 Ca_10251,Ca_09868 01100Metabolicpathways(812)
K00297 Ca_26773 01523Antifolateresistance(7)
K00600 Ca_00054,Ca_00455,Ca_14951,Ca_11397,Ca_08538,Ca_11540,Ca_11173 01523Antifolateresistance(7)

所以,这个 liner 基本上做的是将某些行捕获到变量中。所以第一部分 /^[0-9].*/{ h = $0; next 捕获以数字开头的行,例如您的类别标识符。 awk 看到行 01100metabolicpathway 并将其存储到变量 h 中。然后执行 next 命令,awk 读取下一行。第二部分 /^K/{ k = $0; next } 在一行以 K 开头时执行。就像你的 KO id 一样。 awk 再次将整行存储到一个变量中并继续下一行。现在 las 部分 { print k, $0, h } 在一行不满足任何提到的条件(以 K 或数字开头)时执行。然后是变量k的内容,整行当前行和变量h的内容。这会导致所需的输出。

关于linux - 根据标题类别将行转换为属于不同类别的相应列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46320227/

相关文章:

c++ - C++ Linux 中的线程无限期等待

unix - 了解 uname 输出

linux - 如何在子目录中找到最大的文件?

regex - 将包含特定文本的行从一个文件复制到另一个文件

python - 将坐标表示转换为邻接列表表示

c# - 不将输出写入控制台的处理

linux - 如何将 GNU Screen 复制缓冲区复制到剪贴板?

linux - SED/AWK block 的名字来自全名

bash - 为什么在可执行文件或脚本名称之前需要 ./(点斜杠) 才能在 bash 中运行它?

python - 在python中将指数转换为小数