> 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"
- 您正在使用扩展正则表达式,因此使用
egrep
或grep -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 运行它,以重新转义括号。