我知道可以用-v
标志反转grep输出。有没有办法只输出匹配线的非匹配部分?我问因为我想使用grep的返回码(sed不会有)。以下是我的所得:
tags=$(grep "^$PAT" >/dev/null 2>&1)
[ "$?" -eq 0 ] && echo $tags
答案 0 :(得分:10)
您可以使用sed
:
$ sed -n "/$PAT/s/$PAT//p" $file
唯一的问题是,只要模式好,它就会返回退出代码0,即使找不到模式。
-n
参数告诉sed
不打印任何行。 Sed的默认设置是打印出文件的所有行。让我们看一下斜杠之间sed
程序的每个部分。假设程序为/1/2/3/4/5
:
/$PAT/
:这表示要查找与模式$PAT
匹配的所有行,以运行替换命令。否则,sed
将在所有行上运行,即使没有替换。/s/
:这表示您将进行替换/$PAT/
:这是你要替代的模式。它是$PAT
。因此,您正在搜索包含$PAT
的行,然后您将替换该模式。//
:这就是您要替换$PAT
的内容。它是null。因此,您要从该行中删除$PAT
。/p
:最后p
表示打印出该行。因此:
sed
在处理文件时不要打印出文件的行。$PAT
。s
命令(替换)删除模式。答案 1 :(得分:5)
如何使用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]
保存第二个命令的退出状态,依此类推。
答案 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\ //'
在我看来,你已经把基本概念弄糊涂了。无论如何你还想做什么?