通过阅读,我假设我们不能使用gnu coreutil,并且 egrep 不可用。我假设(出于某种原因)系统已损坏,并且转义无法按预期工作。
在正常情况下,grep -rf patternfile.txt /some/dir/
是要走的路。
包含要搜索的所有字符串列表的文件
假设:gnu coreutil 不可用。grep -r 不起作用。特殊字符的处理被破坏。
现在,你有工作 awk 吗?不 ?。它使生活变得如此轻松。但让我们保持安全。
假设:工作sed
,od
OR hexdump
OR xxd
(来自vim包)之一可用。
让我们称之为 patternfile.txt
1.将list转换成grep喜欢的正则表达式
示例 patternfile.txt 包含
/富/
/酒吧/能源部/
/根/
(示例不打印特殊字符,但它就在那里。)我们必须把它变成类似的东西
(/foo/|/bar/doe/|/root/)
假设echo -en
command 没有损坏,并且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 {} \;
也应该可以工作。有些人可能更喜欢xargs
instaed(除非你碰巧有错误的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
的。让生活变得更美好。