我有一个简单的egrep命令,在文本文件中搜索多个字符串,输出null或值。下面是命令和输出。
cat Output.txt|egrep -i "abc|def|efg"|cut -d ':' -f 2
输出是: -
xxx
(null)
yyy
现在,我正在尝试将我的搜索文本添加到输出中,如下所示。
abc:xxx
def:
efg:yyy
对于实现此目的或从何处开始的代码的任何帮助将不胜感激。
-Abhi
答案 0 :(得分:3)
由于我不确切知道您的输入文件内容(在问题中没有正确指定),我会提出一些假设来回答您的问题。
案例1:您要查找的模式始终位于同一列
如果是这样的话,答案非常简单:
$ cat grep_file.in
abc:xxx:uvw
def:::
efg:yyy:toto
xyz:lol:hey
$ egrep -i "abc|def|efg" grep_file.in | cut -d':' -f1,2
abc:xxx
def:
efg:yyy
grep之后只需使用您要查找的2列剪切(此处为1和2)
备注:
不要cat
文件,pipe
,然后grep
,因为这是两次工作!你的grep命令已经读取了这个文件,所以不要读两遍,对于小文件来说可能不那么重要,但你会觉得10GB
文件有所区别!
案例2:您要查找的模式不在同一列中
在这种情况下,它有点棘手,但并非不可能。有很多方法,在这里我将详细介绍awk
方式:
$ cat grep_file2.in
abc:xxx:uvw
::def:
efg:yyy:toto
xyz:lol:hey
如果您的输入文件采用此格式;你的模式可以位于任何地方:
$ awk 'BEGIN{FS=":";ORS=FS}{tmp=0;for(i=1;i<=NF;i++){tmp=match($i,/abc|def|efg/);if(tmp){print $i;break}}if(tmp){printf "%s\n", $2}}' grep_file
2.in
abc:xxx
def:
efg:yyy
<强>说明:强>
FS=":";ORS=FS
在:
定义您的输入/输出字段分隔符然后在每一行上定义一个测试变量,当您到达模式时,该变量将变为true,您循环该行的所有字段,直到达到它为止如果是你打印它的情况,打破循环并打印第二个字段+一个EOL字符。
如果你不符合你的模式,你什么都不做。
如果您更喜欢sed
方式,可以使用以下命令:
$ sed -n '/abc\|def\|efg/{h;s/.*\(abc\|def\|efg\).*/\1:/;x;s/^[^:]*:\([^:]*\):.*/\1/;H;x;s/\n//p}' grep_file2.in
abc:xxx
def:
efg:yyy
说明:
/abc\|def\|efg/{}
用于过滤仅包含其中一个模式的行,然后执行块中的指令。 h;s/.*\(abc\|def\|efg\).*/\1:/;
将行保存在保留空间中,并用3种模式中的一种替换该行,x;s/^[^:]*:\([^:]*\):.*/\1/;
用于交换模式并保留空间并提取第二列元素。最后但并非最不重要的是,H;x;s/\n//p
用于在1行上重新组合两个提取的元素并打印它。
答案 1 :(得分:1)
试试这个
$ egrep -io "(abc|def|efg):[^:]*" file
将在分隔符后打印匹配和下一个标记。
答案 2 :(得分:0)
如果我们可以假设只有两个字段,abc
等将始终在第一个字段中匹配,并且在包含多个匹配的行上获得最后一个匹配是可以接受的,这非常简单{{ 1}}脚本可以工作。
sed
如果适用其他但类似的条件(例如,有三个或更多字段,但我们不关心前两个字段中的匹配),则所需的修改是微不足道的。如果没有,你真的需要澄清你的问题。