Answers:
我只是将其grep
删除一秒钟:
grep -r --exclude={\*~,\*.map} "OK" bar/ | grep -vP '(?<!debug)\.js'
在-v
逆转的比赛中,打印不匹配的图案与线条-P
使Perl兼容的正则表达式这让我们用负lookbehinds。这个特定的正则表达式,将匹配.js
是不通过prececeded debug
哪个装置(因为我们反转匹配),只有那些.js
文件将被打印。
但是,正如@QuestionOverflow指出int注释一样,这可能会产生意外的副作用,即过滤掉包含和的行,这是因为不仅应用于文件名,而且应用于整个输出。为了避免这种情况,只需添加一个冒号(这就是用来将文件名与文件内容分开的方法):OK
js
grep -v
grep
grep -r --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js:'
如果您的输入行包含foo.js:
或文件名包含,那仍然会失败:
。因此,可以肯定的是,请使用其他方法:
grep -Tr --exclude={*~,*.map} "OK" bar/ | grep -vP '(?<!debug).js\t'
在文件名和文件内容之间打印选项卡的-T
原因grep
。因此,如果我们仅\t
在正则表达式的末尾添加a ,它将仅与文件名匹配,而不与行的内容匹配。
不过,无论如何,使用find
可能更有意义。
find
这种事情可能会更好。grep
如您所指出的,正确的选择可能很棘手:)。
failglob
在shell中设置了选项,您的解决方案将失败: bash: no match: --exclude=*~
您需要引用GLOB模式参数--exclude
以将其从shell扩展中隐藏起来,例如--exclude={\*~,\*.map}
我会find
用来定位文件并通过管道传递结果xargs
:
$ find . -type f \! -name "*~" \
\! -name "*.map" \
\! \( -name "*.js" -and \! -name "*.debug.js" \) \
-print0 | xargs -0 grep "OK"
这将搜索不匹配“ *~
”,“ *.map
”或“ *.js
但不匹配”的每个文件*.debug.js
。
使用find
它可以轻松地搜索相当复杂的规则,并且这种方法可以避免意外删除误报(如double可能发生)grep
。
-exec grep OK {} +
代替xargs
并避免使用额外的程序。
-exec +
不要这样做-exec \;
,那样将运行尽可能少的命令,就像xargs
。
如果您不介意看到输出有点混乱(如果这样做,则可以对其进行排序):
grep -r --exclude={*~,*.map,*.js} "OK" /some/dir **/*.debug.js
这要求您的shell支持**
递归glob:zsh开箱即用,bash在运行后运行shopt -s globstar
,ksh93在运行后运行set -o globstar
。
如果没有**
外壳支持,则可以使用两个grep命令:
grep -r --exclude={*~,*.map,*.js} "OK" /some/dir
grep -r --include=*.debug.js "OK" /some/dir
**
,但是多余的参数似乎出了点问题**/*.debug.js
,导致grep解释OK
为目录。您是否尝试过运行它?
您可以使用ripgrep
。默认情况下,它会忽略隐藏文件并尊重您的.gitignore
文件。
您可以使用以下参数指定包含或排除规则:
-g
/--glob GLOB
包含或排除与给定的glob相匹配的文件和目录。
-t
/--type TYPE
仅搜索与TYPE相匹配的文件。可以提供多种类型的标志。
-T
/--type-not TYPE
不要搜索与TYPE相匹配的文件。使用该
--type-list
标志列出所有可用的类型。
以下是一些简单的示例:
rg -Tjs "OK" # Excludes *.js, *.jsx, *.vue files.
rg -tpy "OK" # Includes Python files.
rg --type-add 'map:*.map' -tmap PATTERN # Excludes *.map files.
rg -g '!*.js' -g '*.debug.js' PATTERN # Excludes *.js apart of *.debug.js.
下面是完整的解决方案来排除*.~
,*.map
,*.js
,但不是*.debug.js
:
rg -g '*.*' -g '!*.~' -g '!*.map' -g '!*.js' -g '*.debug.js' "OK"
测试:
$ touch file.~ file.map file.js file.debug.js file.txt file.md
$ rg --files
file.debug.js
file.js
file.map
file.md
file.txt
$ rg -g '*.*' -g '!*.~' -g '!*.map' -g '!*.js' -g '*.debug.js' --files
file.debug.js
file.md
file.txt
OK
和.js
在同一行?