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

时间:2011-06-20 22:51:53

标签: bash shell unix grep

我知道可以用-v标志反转grep输出。有没有办法只输出匹配线的非匹配部分?我问因为我想使用grep的返回码(sed不会有)。以下是我的所得:

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

3 个答案:

答案 0 :(得分:10)

您可以使用sed

$ sed -n "/$PAT/s/$PAT//p" $file

唯一的问题是,只要模式好,它就会返回退出代码0,即使找不到模式。


解释

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

  1. /$PAT/:这表示要查找与模式$PAT匹配的所有行,以运行替换命令。否则,sed将在所有行上运行,即使没有替换。
  2. /s/:这表示您将进行替换
  3. /$PAT/:这是你要替代的模式。它是$PAT。因此,您正在搜索包含$PAT的行,然后您将替换该模式。
  4. //:这就是您要替换$PAT的内容。它是null。因此,您要从该行中删除$PAT
  5. /p:最后p表示打印出该行。
  6. 因此:

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

答案 1 :(得分:5)

如何使用grepsed$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]保存第二个命令的退出状态,依此类推。

答案 2 :(得分:2)

您的$ tags永远不会有值,因为您将它发送到/ 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\ //'

在我看来,你已经把基本概念弄糊涂了。无论如何你还想做什么?