如果找到则搜索值并打印(BASH)

时间:2017-03-24 14:03:13

标签: bash grep

我有以下列表:

    COX1
    COX1
    COX1
    COX1
    COX1
    Cu-oxidase
    Cu-oxidase_3
    Cu-oxidase_3
    Fer4_NifH

我要搜索列表中是否有COX1Cu-oxidase,我想打印xyz,如果Cu-oxidase_3Fer4_NifH在也是列表(如果前两个在列表中是独立的,那么它应该打印abc

这是我到目前为止的脚本:

if grep 'COX1' file.txt; then echo xyz; else exit 0; fi

但它当然是不完整的。 任何解决方案?

理想情况下,我的输出是:

xyz
abc

2 个答案:

答案 0 :(得分:0)

Awk可让您轻松搜索多个正则表达式,并打印除匹配字符串本身以外的其他内容。 (grep也可以轻松搜索多个模式,但它会打印匹配或其行号或文件名,而不是一些任意字符串。)

以下假设您每行都有一个令牌。这个假设使脚本非常简单,但支持其他场景也不难。

awk '{ a[$1]++ }
    END { if (("COX1" in a) && ("Cu-oxidase" in a)) print "xyz";
        if (("Cu-oxidase_3" in a) && ("Fer4_NifH" in a)) print "abc" }' file.txt

这构建了每个标记的关联数组(实际上是每行上第一个以空格分隔的标记),然后在最后,当它读取文件中的每一行时,检查所寻找的标记是否作为数组中的键存在

对输入文件执行单次传递是一项重大胜利,尤其是如果您有大量输入文件和许多模式。为了完整起见,使用grep执行多次传递的语法非常简单;

if grep -qx 'COX1' file.txt && grep -qx 'Cu-oxidase' file.txt
then
    echo xyz
fi

可以进一步缩写为

grep -qx 'COX1' file.txt && grep -qx 'Cu-oxidase' file.txt && echo xyz

注意-x开关要求整行匹配(否则正则表达式'Cu-oxidase'也会匹配 Cu-oxidase_3 行。

答案 1 :(得分:-1)

以上是实现这一目标的非常冗长的方式。有一些方法可以用较少的if和更少的grep来编写相同的内容,但我真的想向您展示逻辑:

运行grep命令,使用$?检查其返回值,最后根据条件执行操作。

# default values
HAS_COX1=0
HAS_CUOX=0
HAS_CUO3=0
HAS_FER4=0

# run silently grep
grep -q 'COX1' file.txt
# check for return value and set variable accordingly
if [ $? -eq 0 ]; then HAS_COX1=1; fi

# same as above
grep -q 'Cu-oxidase' file.txt
if [ $? -eq 0 ]; then HAS_CUOX=1; fi
grep -q 'Cu-oxidase_3' file.txt
if [ $? -eq 0 ]; then HAS_CUO3=1; fi
grep -q 'Fer4_NifH' file.txt
if [ $? -eq 0 ]; then HAS_FER4=1; fi

if [ $HAS_COX1 -eq 1 ]; then
  if [ $HAS_CUOX -eq 1 ]; then
    echo 'xyz'
    exit 0
  fi
fi

if [ $HAS_CUO3 -eq 1 ]; then
  if [ $HAS_FER4 -eq 1 ]; then
    echo 'abc'
    exit 0
  fi
fi

echo 'None of the checks where matched'
exit 1

注意:此代码未经测试,因此可能存在错误☺

代码并不完美,因为当满足这两个条件时,它无法同时打印'xyz''abc'(但这可以通过我提供的语法轻松修复)。每当找到$HAS_CUOX时,1也会设置为$HAS_CUO3grep正则表达式中没有边界检查)。

您可以使用单个grep为每组条件进行检查,使用'COX1\|Cu_oxidase'作为grep的正则表达式来进一步获取该代码。并解决了我上面提到的小问题。

  

理想情况下,我的输出将是:   xyz   abc

在我编写完上述脚本后添加了您的预期输出,但考虑到我给你的元素,你应该能够想出如何改进它(基本上删除放置它们的exit 0,然后执行{ {1}}当没有给出输出时。

或者只删除所有exit 1作为脏解决方案。