如何在UNIX TRU64环境中对文件中的字符串执行递归目录搜索?

时间:2010-11-04 09:47:41

标签: unix find grep xargs

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

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

即:
/ AAA / BBB / CCC
/ EEE / DDDD / GGGGGGG /
等。

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

我在调查期间发现的一个例子可能很接近,但我不知道如何自定义这个以接受字符串参数文件:

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

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

2 个答案:

答案 0 :(得分: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

在某些情况下可能会更强大/更有效。

答案 1 :(得分:1)

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

在正常情况下,grep -rf patternfile.txt /some/dir/是可行的方法。

  

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

假设:gnu coreutil不可用。 grep -r不起作用。特殊性格的处理被打破了。

现在,你有工作awk?不是吗?它让生活变得如此简单。但是,为了安全起见。

假设:工作sed,其中一个odhexdumpxxd(来自vim包)。

让我们调用这个patternfile.txt


1。将列表转换为grep喜欢的正则表达式

示例patternfile.txt包含

  

/富/

     

/酒吧/ DOE /

     

/根/

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

这样的东西

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

假设echo -en命令没有被破坏,xxdodhexdump可用,

使用hexdump

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')")"

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

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. 将它变成更小的块。现在这是一个严重破坏的系统。 那么for file in file-smaller-chunk.part.* ; do for single_line in cat "$file" ; do grep REGEXP_PATTERN "$single_line" ; done ; done ; 应该工作。

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

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

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

awkperl,无论如何都可以做得更好,但是因为我们将自己限制为 sed,让我们这样做。 我们假设0x27, the ' code实际上会起作用。 cat list-of-all-file-to-search-for.txt |sed 's@['\'']@'\''\\'\'\''@g'|sed 's:^:'\'':g'|sed 's:$:'\'':g' 我唯一需要使用的是将输出再次输入bash。

如果我的shell没有处理该怎么办?

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

我们有其他的东西吗? YES。

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

但你知道吗,我登上了,并为csh编写自动化脚本 错误。所以我要停在这里。

带回家注意

使用该工具进行正确的工作。在bc上写一个翻译是完美的 能干,但这是完全错误的。安装coreutils,perl,更好grep 随你。让生活变得更美好。