这个 grep 有什么问题吗?

这个 grep 有什么问题吗?
> output2.txt
cd # some directory i'm trying to search
find views/shared -type f -name "*.js" -print0 | while IFS= read -r -d $'\0' line; do
    echo -n "${line%.js}" | tee -a ~/Documents/counter/output2.txt
    grep -lr "${line%.js}" . | wc -l | tee -a ~/Documents/counter/output2.txt   # produce a count of occurrences
    regex='[a-zA-Z]+.extend'
    grep -f $line $regex
    grep -lr "${line%.js}" . | tee -a ~/Documents/counter/output2.txt           # produce a list of occurrences
done

退货

grep: brackets ([ ]) not balanced

我在网上看到的所有例子似乎都表明这里没有任何问题,所以我很困惑

方括号肯定是平衡的,不是吗?

答案1

你的问题是-f选项。不指定要搜索的文件,而是-f指定从中读取模式列表的文件。 OS X grep 的手册页对此进行了解释不太清楚:

 -f file, --file=file
         Read one or more newline separated patterns from file.  Empty pattern lines match every input
         line.  Newlines are not considered part of a pattern.  If file is empty, nothing is matched.

GNU grep 的帮助实际上更简单:

$ grep --help | grep -- '-f,'
  -f, --file=FILE           obtain PATTERN from FILE
$ 

-f根据 GNU grep 的手册页,这种行为是:specified by POSIX.

您的修复可能是更改您的线路:

grep -f $line $regex

到:

egrep "$regex" -- "$line"
  • 您正在使用扩展正则表达式,因此使用egrepgrep -E
  • --将阻止grep解析变量中的任何选项,例如,它将保护您免受名为“ ”$line的文件的侵害-r funnyname.js

答案2

如果进入 grep 管道的输入包含方括号(“[”和“]”),grep 将很难优雅地处理它们。您必须首先使用类似的方法“清理”输入,将每个方括号括在一对方括号中,从而使它们被解释为要匹配的文字字符:

CommandYouWantToPipeThroughGREP | sed -e 's^\([][]\)^\[\1\]^g' | grep ...

sed命令解释:

sed -e: -e 后面是一个表达式。它必须用单引号或双引号括起来。

s^: [搜索。 “^”用作字段分隔符。每次您看到“^”时,它都会界定搜索选项的新部分。

\(...\)\1: 转义括号包含您希望能够作为 sed 中的变量访问的模式。第一个这样的模式被称为“\1”;第二个是“\2”,依此类推。

[][]:外部两个支架包围内部两个支架。 “[”之后的第一个字符被自动假定为文字(转义/没有特殊含义)。由于第一个字符是括号,因此下一个括号也被假定为文字,除非它是该“^”分隔字段末尾之前的唯一括号。 (至少,这是我对其工作原理的理解......)

\[\1\]:将 sed 变量 1 ("\1") 括在方括号中,并将其发送到输出。

g: [贪婪的。这意味着“查找并替换搜索文本的所有示例,而不仅仅是第一个”。

因此,只需通过此 sed 命令通过管道传输任何可能包含方括号的输入,然后再通过 grep 进行管道传输,grep 会按字面意思查找括号,而不是将它们解释为特殊字符。不幸的是,如果您在第一个命令之后通过管道传输到另一个 grep 命令,则似乎需要再次通过 sed 运行它,以重新转义括号。

相关内容