Bash grep一个模式并输出行的不匹配部分

Bash grep一个模式并输出行的不匹配部分,bash,shell,unix,grep,Bash,Shell,Unix,Grep,我知道可以使用-v标志反转grep输出。有没有办法只输出匹配行的非匹配部分?我这样问是因为我想使用grep的返回码(sed没有)。以下是我得到的一些信息: tags=$(grep "^$PAT" >/dev/null 2>&1) [ "$?" -eq 0 ] && echo $tags 您可以使用sed: $ sed -n "/$PAT/s/$PAT//p" $file 唯一的问题是,只要模式良好,即使找不到模式,它也会返回0的退出代

我知道可以使用
-v
标志反转grep输出。有没有办法只输出匹配行的非匹配部分?我这样问是因为我想使用grep的返回码(sed没有)。以下是我得到的一些信息:

tags=$(grep "^$PAT" >/dev/null 2>&1)
[ "$?" -eq 0 ] && echo $tags 

您可以使用
sed

$ sed -n "/$PAT/s/$PAT//p" $file
唯一的问题是,只要模式良好,即使找不到模式,它也会返回0的退出代码


解释
-n
参数告诉
sed
不要打印任何行。Sed的默认设置是打印出文件的所有行。让我们看看斜杠之间的
sed
程序的每个部分。假设程序是
/1/2/3/4/5

  • /$PAT/
    :这表示查找与模式匹配的所有行以运行替换命令。否则,
    sed
    将在所有行上运行,即使没有替换
  • /s/
    :这表示您将进行替换
  • /$PAT/
    :这是您将要替换的模式。这是
    $PAT
    。因此,您要搜索包含
    $PAT
    的行,然后用模式替换某些内容
  • /
    :这就是您要替换的
    $PAT
    。它是空的。因此,您正在从行中删除
    $PAT
  • /p
    :这个最后的
    p
    表示要打印出行
  • 因此:

    • 您告诉sed在处理文件行时不要打印这些行
    • 您正在搜索包含
      $PAT
      的所有行
    • 在这些行中,您使用
      s
      命令(替换)删除模式
    • 一旦图案从线条上移除,您就可以打印线条

    如何结合使用
    grep
    sed
    $PIPESTATUS
    来获得正确的退出状态

    $ echo Humans are not proud of their ancestors, and rarely invite
      them round to dinner | grep dinner | sed -n "/dinner/s/dinner//p"
    Humans are not proud of their ancestors, and rarely invite them round to 
    
    $ echo $PIPESTATUS[1]
    0[1]
    

    $PIPESTATUS
    数组的成员持有在管道中执行的每个相应命令的退出状态
    $PIPESTATUS[0]
    保存管道中第一个命令的退出状态,
    $PIPESTATUS[1]
    保存第二个命令的退出状态,依此类推。

    您的$标记将永远不会有值,因为您将其发送到/dev/null。除了这个小问题,grep没有任何输入

    echo hello |grep "^he" -q ; 
    ret=$? ; 
    if [ $ret -eq 0 ]; 
    then 
    echo there is he in hello; 
    fi
    
    成功的返回代码为0

    …以下是我对你的“问题”的看法:

    pat="most of "; 
    data="The apples are ripe. I will use most of them for jam.";  
    echo $data |grep "$pat" -q; 
    ret=$?; 
    [ $ret -eq 0 ] && echo $data |sed "s/$pat//"
    The apples are ripe. I will use them for jam.
    
    。。。完全一样吗

    echo The apples are ripe. I will use most of them for jam. | sed ' s/most\ of\ //'
    

    在我看来,你把基本概念弄糊涂了。你到底想干什么

    像是
    -o
    做的事情的相反吗?@Steve Prentice是的,类似的事情。出于我的目的,我只需要这行的其余部分。谢谢,但如果我能得到退出代码就好了。我想sed从来没有实现过退出代码,因为它没有真正的意义。@Dennis Hodapp:sed不会给你零以外的退出状态,因为即使它没有编辑任何东西,它也能工作。您只需执行
    if[-z$tags]
    测试是否设置了
    $tag
    。或者,您可以通过
    sed
    通过管道
    grep
    ,然后通过
    $PIPESTATUS
    环境变量获取
    grep
    的退出状态,因为grep可能会找到一些东西,但不会设置任何标记。如果我知道你需要做什么,我可以提供更多的信息。在您原来的帖子中,
    grep
    在命令行中没有文件名。
    grep
    的输入是否取自标准输出?我的问题不是很好,我抄错了。我忘了添加输入文件,它是一个有多行的文件。你的回答(加上评论)也正是我想要的。不过我不能把答案给两个人。如果你能解释一下上面sed语法的一般形式,那就太好了。i、 例如,
    /$pat/s/$pat//p
    在sed语言中到底是什么意思?这个语法的应用是如何解决OP的问题的?提问,你们就会得到答案。看上面的解释。是的,这对我来说很糟糕。我想我抄错了,但那无关紧要。关键是要使用grep找到一个模式。我要返回代码,然后是行中不匹配的部分。当我进一步了解它时,除了尝试编写更少的代码(一个grep命令)之外,实际上没有其他意义。上面的弗雷德里克似乎以一种有趣的方式解决了我的问题,但你的方法也很有效。这很酷。我不知道现在的状况。以下所有答案都很好,但这与我想要的最接近。