0

我在 ~/.bash_profile 中编写了以下过滤器作为函数:

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 转义码突出显示匹配项。

例如,以下查找并突出显示字符串binU1,它们是 /etc/passwd 的最后 10 行中的整个单词:

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

然而,脚本运行非常缓慢,因为每一行都分叉了一个 echo、egrep 和 sed。

在这种情况下,对整个输入执行 egrep 并在其输出上运行 sed 会更有效。

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

PS有没有另一种方法可以以类似的方式查找和突出显示线条?

4

5 回答 5

2

我认为您可以简单地替换整个while循环

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

因为sed可以逐行从标准输入读取,所以你不需要read

我不确定运行egrep和管道sed是否比sed单独使用更快,但您始终可以比较使用time.

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

于 2012-10-31T14:34:57.237 回答
2

如果您egrep支持--color,只需将其放在 .bash_profile 中:

  hilite() { command egrep --color=auto "$@"; }

(就个人而言,我将函数命名为egrep;因此使用command)。

于 2012-10-31T15:10:48.713 回答
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等。

于 2012-10-31T19:10:03.983 回答
1

好吧,你可以简单地这样做:

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

但我不确定它会快得多;)

于 2012-10-31T12:28:56.140 回答
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"
于 2012-11-01T20:05:46.877 回答