找到特定的tet并将其打印到同一列 - awk,sed

时间:2014-07-16 14:44:42

标签: bash awk sed match

我有.tsv INPUT有两列。

cosmic=1559412:35423    dbsnp=rs80358762
cosmic=23930
dbsnp=rs80359637:rs80358961
cosmic=172579:172578    dbsnp=rs80358435
cosmic=219056    dbsnp=rs80359350:rs80359351:rs80359352:rs80359353

我想要一个专栏。输出:

dbsnp=rs80358762
N/A
dbsnp=rs80359637:rs80358961
dbsnp=rs80358435 
dbsnp=rs80359350:rs80359351:rs80359352:rs80359353

我试过

awk a=/dbsnp/'{print $a }' dbsnp.tsv 

但这是个坏主意。或者使用MATCH。 你能帮我吗...

6 个答案:

答案 0 :(得分:2)

使用awk的一种方法

awk '{for(i=1;i<=NF;i++)if($i~/dbsnp/)print $i}!/dbsnp/{print "N/A"}' dbsnp.tsv

您在评论中几乎已经将其与dbsnp匹配$i=="dbsnp",但这些字段包含其他内容。如果字段包含$i~/dbsnp/

,则使用dbsnp匹配

答案 1 :(得分:2)

由于您还可以使用sed解决方案,因此您可以简单地删除&#34; cosmic&#34;柱:

sed 's/cosmic=[^[:space:]]*[[:space:]]*//' input.tsv

这只是将违规列替换为不存在。

如果您确实希望在找不到任何内容时输出N/A,则可以执行以下操作:

sed -ne 's/cosmic=[^[:space:]]*[[:space:]]*//;s:^$:N/A:;p' input.tsv

这与以前的替换相同,但用&#34; N / A&#34;替换空行。

Proviso: Per ams&#39;准确观察,[:space:]与标签(您的分隔符)不同。为了正确处理您的输入(其中&#34; cosmic&#34;可能包含空格),请用文字标签替换[:space:]


由于您还可以使用bash解决方案,因此无需任何外部工具即可实现此目标:

shopt -s extglob;
while read line; do
  echo "${line/cosmic=+([^$'\t'])?([$'\t'])/}";
done < input.tsv

同样,要用N/A替换空白行,需要更多逻辑:

shopt -s extglob;
while read line; do
  line="${line/cosmic=+([^$'\t'])?([$'\t'])/}";
  test -z "$line" && echo "N/A" || echo "$line";
done < input.tsv

尾随的分号当然是多余的;我已将它们留在这里,以便您可以根据需要轻松地将它们复制并粘贴到单行中。

请注意,如果您需要extglob模式表达式,则需要设置+(...),这对于这种复杂的文本解析非常需要。

答案 2 :(得分:2)

$ awk -F'\t' '{print ($NF~/^dbsnp=/ ? $NF : "N/A")}' file
dbsnp=rs80358762
N/A
dbsnp=rs80359637:rs80358961
dbsnp=rs80358435
dbsnp=rs80359350:rs80359351:rs80359352:rs80359353

答案 3 :(得分:1)

这应该有效:

awk -F '\t' 'NF > 1 {print $2; next} /^dbsnp=/ {print $1; next} /.*/ {print "N/A"}' dbsnp.tsv

这说:

  1. 如果有多个字段,请使用第二个字段,然后移动下一行。

  2. 否则,如果第一个(也是唯一的)字段以dbnsp=开头,则打印出来,然后移至下一行。

  3. 否则,只需打印&#34; N / A&#34;。 (/.*/匹配所有内容。)

  4. next很重要,因为这会增加&#34;否则&#34;遵守以下规则。

答案 4 :(得分:1)

那个简单的 sed命令没有做到这一点吗?

sh$ sed -n -e 's/^.*dbsnp=/dbsnp=/p' -e '/^dbsnp=/!c N/A' < dbsnp.tsv
dbsnp=rs80358762
N/A
dbsnp=rs80359637:rs80358961
dbsnp=rs80358435
dbsnp=rs80359350:rs80359351:rs80359352:rs80359353

我认为这很容易适应数据文件的各种细微之处。

答案 5 :(得分:1)

命令:

sed -r 's/.*(dbsnp=.*)/\1/;TM;p;d;:M;c\N/A' dbsnp.tsv

输出:

dbsnp=rs80358762
N/A
dbsnp=rs80359637:rs80358961
dbsnp=rs80358435
dbsnp=rs80359350:rs80359351:rs80359352:rs80359353