这个看似简单,我想我错过了一些明显的东西......但是我一直无法找到一种有效的方法来生成一个列表:
...在我通过单行排除子模式消除大多数匹配(catch)的情况下。
在大约~1,300
个感兴趣的代码文件中,~1,000
包含{brandedTerm}
,基于以下检查:
可能匹配的感兴趣的代码文件数量(基于扩展名):
( printf "%s\n" $( find . -type f -name "*.{extension}" ) )| wc -l
包含术语的代码文件数量:
( printf "%s\n" $( find . -type f -name "*.{extension}" -exec grep -l "{brandedTerm}" {} \; ) )| wc -l
问题是这些匹配大部分都是我不关心的子模式,因为它们是注释或枚举名称等。我正在努力追捕的是在字符串中使用{brandedTerm}
来修改/混淆研究的少量用例。
我几乎可以达到我想要的水平:
find . -type f -name "*.{extension}" -exec grep "{brandedTerm}" {} \; | sed -e '/{exclusion_pattern_1}/d; ... /{exclusion_pattern_k}/d'
...其中{exclusion_pattern_1}
,...,{exclusion_pattern_k}
表示与我不关心的子匹配相匹配的模式(大多数匹配)。
自我打印匹配(2.
)后排除。唯一的问题是没有列出在(1.
)中找到这些后排除匹配项的文件;我希望编辑这些比赛的必要性。
我摆弄的大多数途径(循环匹配文件和连接文件名/匹配然后排除 OR 重新搜索匹配模式w /排除应用)经证明是繁重而缓慢的。
我认为有一些更简单的方法来查找文件&在以下情况下打印其匹配内容w / exclusions:
思想?
(另外,如果有重复请告诉我......在这个具体情况下无法找到任何内容,但是awk
/ sed
是很好的,所以我很谨慎我没有找到正确的搜索短语来找到一些预先存在的答案。)
答案 0 :(得分:1)
使用GNU awk,这将查找当前目录中包含正则表达式ext
但不包含brandedTerm
或exclude1
的扩展名exclude2
的所有文件:
awk '/brandedTerm/{f=1} /exclude1/ || /exclude2/{g=1; nextfile} ENDFILE{if (f && !g) print FILENAME; f=0;g=0}' *.ext
对于那些喜欢的人,同一个命令分散在多行上,如下所示:
awk '/brandedTerm/{
f=1
}
/exclude1/ || /exclude2/{
g=1
nextfile
}
ENDFILE{
if (f && !g)
print FILENAME
f=0
g=0
}' *.ext
要将上述内容应用于当前目录中的所有文件,并递归遍历以.ext
结尾的子目录,请使用find
:
find . -type f -name '*.ext' -execdir awk '/brandedTerm/{f=1} /exclude1/ || /exclude2/{g=1; nextfile} ENDFILE{if (f && !g) print FILENAME; f=0;g=0}' {} +
Awk将逐行循环遍历参数列表中的每个文件。
/brandedTerm/{f=1}
如果当前行与正则表达式brandedTerm
匹配,则将f
设置为1(true)。
/exclude1/ || /exclude2/{g=1; nextfile}
如果当前行包含正则表达式exclude1
或exclude2
,则将g
设置为1(true)并跳过文件的其余部分。
ENDFILE{if (f && !g) print FILENAME; f=0;g=0}
在每个文件的末尾,如果f
为真且g
不是,则打印文件名。然后,将f
和g
都设置为零。
对于缺少nextfile
和ENDFILE
功能的awks:
find . -type f -name '*.ext' -execdir awk '/brandedTerm/{f=1} /exclude1/ || /exclude2/{g=1; nextfile} END{if (f && !g) print FILENAME}' {} \;
要显示包含brandedTerm
但不包含exclude1
或exclude2
的文件中的每一行,请尝试:
find . -type f -name '*.ext' -exec awk '/brandedTerm/ && (!/exclude1|exclude2/) {if (!f)print "File "FILENAME; f=1; print}' {} \;
例如,请考虑以下三个感兴趣的文件:
$ cat dir/good1.ext
brandedTerm
exclude1 exclude2
$ cat dir/good2.ext
brandedTerm 1
exclude1 exclude2
brandedTerm 2
brandedTerm 3
$ cat dir/bad1.ext
brandedTerm exclude2
other line
如果我们运行命令,我们会发现:
$ find . -type f -name '*.ext' -exec awk '/brandedTerm/ && (!/exclude1|exclude2/) {if (!f)print "File "FILENAME; f=1; print}' {} \;
File ./dir/good2.ext
brandedTerm 1
brandedTerm 2
brandedTerm 3
File ./dir/good1.ext
brandedTerm
答案 1 :(得分:0)
我们的朋友 find 允许链接多个-exec语句。
find . -type f -name "*.{extension}" \
-exec grep -q "{brandedTerm}" {} ";" \
-exec egrep -v "excl_1|excl_2|excl_3" {} ";"
注意第一个grep中的q,将其设置为安静,以及egrep,它允许添加多个模式以排除(-v)| (要么)。