2012-10-31 85 views
0

我写了下面的过滤器的功能在命令我在〜/ .bash_profile:加快bash的过滤功能,以连续运行,而不是每行

hilite() { 
export REGEX_SED=$(echo $1 | sed "s/[|()]/\\\&/g") 
while read line 
do 
    echo $line | egrep "$1" | sed "s/$REGEX_SED/\x1b[7m&\x1b[0m/g" 
done 
exit 0 
} 

找到管道输送到它匹配正的东西线表达式,并在VT100兼容终端上使用ANSI转义码突出显示匹配项。

例如,以下的发现,并突出琴弦ü或这是在最后10行的整个单词/ etc/passwd中:

tail /etc/passwd | hilite "\b(bin|[U1])\b" 

然而,脚本运行速度非常缓慢,因为每行都会分叉echo,egrep和sed。

在这种情况下,这将是更有效地做的egrep对整个输入,然后在其输出端运行的sed。

如何修改我的函数来做到这一点?如果可能,我宁愿不创建任何临时文件。

P.S.是否有另一种方式来以类似的方式查找和突出显示线条?

+2

'退出0'可能不是你想要的。如果你不小心输入了尾部文件; hilite foo',你的shell将终止!使用':','真','返回0',或者只是删除'出口0'线完全。 –

+0

@WilliamPursell:你说得对,谢谢!猜测http://stackoverflow.com/questions/5104426/while-loop-in-bash-script也应该修正... – Gnubie

回答

2

sed可以做一些自己的grepping:如果你给它-n标志(或脚本中的#n指令),它不会回应任何输出,除非询问。所以

while read line 
do 
    echo $line | egrep "$1" | sed "s/$REGEX_SED/\x1b[7m&\x1b[0m/g" 
done 

可以简化为

sed -n "s/$REGEX_SED/\x1b[7m&\x1b[0m/gp" 

编辑: 这里的整体功能:

hilite() { 
    REGEX_SED=$(echo $1 | sed "s/[|()]/\\\&/g"); 
    sed -n "s/$REGEX_SED/\x1b[7m&\x1b[0m/gp" 
} 

这一切就是这么简单 - 没有while循环,阅读,grepping等。

+1

不,不需要egrep的。使用'-n'和'p'标志的全部意思是不打印任何东西,除非它匹配。这与grep完全一样。 'sed -n'/ foo/p''只是写'grep foo'的另一种方法。 –

1

嗯,你可以简单地这样做:

egrep "$1" $line | sed "s/$REGEX_SED/\x1b[7m&\x1b[0m/g" 

但我不知道它会快很多; )

+1

我不知道,但'回声'可能比'egrep更轻'和'sed'。反正不会'egrep'治疗'$ line'作为一个文件来在你写的命令行解析? – doubleDown

+0

对不起,语法是egrep的作为doubleDown评论。 – Gnubie

+0

是的,你是对的,我误解了原来的问题... – tamasgal

2

我认为你可以简单地

sed -n "s/$REGEX_SED/\x1b[7m&\x1b[0m/gp" 

因为sed可以从标准输入读取更换整个while环行由行,所以你不需要read

我不知道如果运行egrep和管道到sed比单独使用sed更快,但你总是可以比较使用time

编辑:添加-npsed仅打印突出显示的行。

+0

修正了简单地使用'-n'选项并设置's'命令的'p'标志 – doubleDown

2

如果您egrep支持--color,只是把这个中的.bash_profile:

hilite() { command egrep --color=auto "[email protected]"; } 

(就个人而言,我会命名功能egrep;因此的command使用)。

+0

尽管我更喜欢反向视频,那太棒了!也可以使用GREP_COLOR或GREP_COLORS更改颜色:http://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html。对于单个命令:http://stackoverflow.com/questions/3420845/in-bash-how-to-write-alias-or-function-for-export-grep-color-132-grep-co。 – Gnubie

0

只是为了记录在案,这是使用临时文件的方法:

hilite() { 
export REGEX_SED=$(echo $1 | sed "s/[|()]/\\\&/g") 
export FILE=$2 
if [ -z "$FILE" ] 
then 
    export FILE=~/tmp 
    echo -n > $FILE 
    while read line 
    do 
    echo $line >> $FILE 
    done 
fi 
egrep "$1" $FILE | sed "s/$REGEX_SED/\x1b[7m&\x1b[0m/g" 
return $? 
} 

这也需要一个文件/路径名作为第二个参数,对于像的情况下

cat /etc/passwd | hilite "\b(bin|[U1])\b"