不幸的是,由于Unix Tru64环境的限制,我无法使用GREP -r开关在多个目录和子目录中的文件中搜索字符串。
理想情况下,我想传递两个参数。第一个是我希望我的搜索开始的目录。第二个是包含要搜索的所有字符串列表的文件。此列表将包含各种目录路径名称,并包含特殊字符:
即:
/ AAA / BBB / CCC
/ EEE / DDDD / GGGGGGG /
等。
本练习的目的是识别可能在列表中标识的特定硬编码路径名的所有shell脚本。
我在调查期间发现的一个例子可能很接近,但我不知道如何自定义这个以接受字符串参数文件:
例如:find etb -exec grep test {} \;
其中'etb'是目录,'test'是要搜索的硬编码字符串。
答案 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
,其中一个od
或hexdump
或xxd
(来自vim包)。
让我们调用这个patternfile.txt
示例patternfile.txt包含
/富/
/酒吧/ DOE /
/根/
(示例不打印特殊字符,但它就在那里。)我们必须把它变成像
这样的东西 (/foo/|/bar/doe/|/root/)
假设echo -en
命令没有被破坏,xxd
或od
或hexdump
可用,
使用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'
并且你有一个转义的正则表达式模式。
假设可以使用最小的shell转义,
我们使用grep "$(echo -en "ESCAPED_PATTERN" )"
来完成我们的工作。
构建转义的正则表达式模式(使用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')")"
将转义所有字符并用(|)括号括起来,以便执行正则表达式或匹配。
在正常情况下,即使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不处理引号怎么办?
您可能必须事先转义文件列表。
在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。
如果我的shell没有处理该怎么办?
xargs
失败,grep -r
失败,shell的for循环失败。
我们有其他的东西吗? YES。
转义适合您的shell的所有输入,并制作一个脚本。
但你知道吗,我登上了,并为csh编写自动化脚本 错误。所以我要停在这里。
使用该工具进行正确的工作。在bc
上写一个翻译是完美的
能干,但这是完全错误的。安装coreutils,perl
,更好grep
随你。让生活变得更美好。