2

不幸的是,由于我们的 Unix Tru64 环境的限制,我无法使用 GREP -r 开关在多个目录和子目录的文件中执行字符串搜索。

理想情况下,我想传递两个参数。第一个将是我希望开始搜索的目录。第二个是包含要搜索的所有字符串列表的文件。此列表将包含各种目录路径名称,并将包含特殊字符:

即:
/aaa/bbb/ccc
/eee/dddd/ggggggg/
等。

本练习的目的是识别所有可能具有在我的列表中标识的特定硬编码路径名的 shell 脚本。

我在调查期间发现了一个可能接近的示例,但我不确定如何自定义它以接受字符串参数文件:

例如:find etb -exec grep test {} \;

其中“etb”是目录,“test”是要搜索的硬编码字符串。

4

2 回答 2

1

这应该这样做:

find dir -type f -exec grep -F -f strings.txt {} \;

dir是开始搜索的目录

strings.txt是要匹配的字符串文件,每行一个

-F意味着将搜索字符串视为文字而不是正则表达式

-f strings.txt表示使用字符串strings.txt进行匹配

-l如果您只想要匹配的文件名,您可以添加到 grep 开关。

脚注:

有些人更喜欢涉及的解决方案xargs,例如

find dir -type f -print0 | xargs -0 grep -F -f strings.txt

在某些情况下,这可能更健壮/高效。

于 2010-11-04T09:58:41.243 回答
1

通过阅读,我假设我们不能使用gnu coreutil,并且 egrep 不可用。我假设(出于某种原因)系统已损坏,并且转义无法按预期工作。

在正常情况下,grep -rf patternfile.txt /some/dir/是要走的路。

包含要搜索的所有字符串列表的文件

假设:gnu coreutil 不可用。grep -r 不起作用。特殊字符的处理被破坏。

现在,你有工作 awk 吗?不 ?。它使生活变得如此轻松。但让我们保持安全。

假设:工作sedodOR hexdumpOR xxd(来自vim包)之一可用。

让我们称之为 patternfile.txt


1.将list转换成grep喜欢的正则表达式

示例 patternfile.txt 包含

/富/

/酒吧/能源部/

/根/

(示例不打印特殊字符,但它就在那里。)我们必须把它变成类似的东西

(/foo/|/bar/doe/|/root/)

假设echo -encommand 没有损坏,并且xxd, or od, orhexdump可用,

使用十六进制转储

cat patternfile.txt |hexdump -ve '1/1 "%02x \n"' |tr -d '\n'

使用 od

cat patternfile.txt |od -A none -t x1|tr -d '\n'

并将其通过管道输入(对于 hexdump 和 od 都很常见), |sed 's:[ ]*0a[ ]*$::g'|sed 's: 0a:\\|:g' |sed 's:^[ ]*::g'|sed 's:^: :g' |sed 's: :\\x:g' 然后将结果通过管道输入 |sed 's:^:\\(:g' |sed 's:$:\\):g' ,您就有了一个转义的正则表达式模式。


2. 将转义模式输入损坏的正则表达式

假设可以使用最低限度的 shell 转义,我们就grep "$(echo -en "ESCAPED_PATTERN" )"可以完成我们的工作。


3. 总结

构建转义的正则表达式模式(以 hexdump 为例)

grep "$(echo -en "$( cat patternfile.txt |hexdump -ve '1/1 "%02x \n"' |tr -d '\n' |sed 's:[ ]*0a[ ]*$::g'|sed 's: 0a:\\|:g' |sed 's:^[ ]*::g'|sed 's:^: :g' |sed 's: :\\x:g'|sed 's:^:\\(:g' |sed 's:$:\\):g')")"

将转义所有字符并用 (|) 括号括起来,因此将执行正则表达式 OR 匹配。

4.递归目录查找

在正常情况下,即使grep -r坏了,find /dir/ -exec grep {} \;也应该可以工作。有些人可能更喜欢xargsinstaed(除非你碰巧有错误的xargs)。我们更喜欢find /somedir/ -type f -print0 |xargs -0 grep -f 'patternfile.txt'方法,但由于这不可用(无论出于何种正当原因),我们需要grep为每个文件执行,这通常是错误的方法。但是让我们去做吧。

假设:find -type f有效。假设:xargs已损坏或不可用。

首先,如果您的管道有问题,它可能无法处理大量文件。所以我们避免xargs在这样的系统中(我知道,我知道,让我们假装它坏了)。

find /whatever/dir/to/start/looking/ -type f > list-of-all-file-to-search-for.txt

如果你的 shell 能很好地处理大尺寸的列表, for file in cat list-of-all-file-to-search-for.txt ; do grep REGEXP_PATTERN "$file" ; done ; 这是一个很好的解决方法。不幸的是,有些系统不喜欢这样,在这种情况下,您可能需要 cat list-of-all-file-to-search-for.txt | split --help -a 4 -d -l 2000 file-smaller-chunk.part. 将其变成更小的块。现在这是一个严重损坏的系统。那么 afor file in file-smaller-chunk.part.* ; do for single_line in cat "$file" ; do grep REGEXP_PATTERN "$single_line" ; done ; done ; 应该工作。

A cat filelist.txt |while read file ; do grep REGEXP_PATTERN $file ; done ; 可以用作某些系统上的解决方法。

如果我的外壳不处理引号怎么办?

您可能必须事先转义文件列表。

awk它可以在, ,中做得更好perl,但是由于我们将自己限制在 sed, 让我们这样做。我们假设0x27, the ' code 实际上会起作用。 cat list-of-all-file-to-search-for.txt |sed 's@['\'']@'\''\\'\'\''@g'|sed 's:^:'\'':g'|sed 's:$:'\'':g' 我唯一一次必须使用它是再次将输出输入 bash 时。

如果我的外壳不能处理怎么办?

xargs失败,grep -r失败,shell 的 for 循环失败。

我们还有其他事情吗?是的。

转义所有适合您的 shell 的输入,并制作一个脚本。

但是你知道吗,我得到了董事会,为 csh 编写自动化脚本似乎是错误的。所以我要在这里停下来。

带回家笔记

使用该工具完成正确的工作。写一个解释器bc是完全有能力的,但这完全是错误的。安装 coreutils,perl一个更好grep 的。让生活变得更美好。

于 2010-11-04T12:35:41.543 回答