2009-10-02 120 views
0

我是新手bash脚本(和* nix shell完全),但我正在尝试编写此脚本以使代码库变得更简单。从bash脚本调用grep

我写了这个

#!/bin/bash 
args=("[email protected]"); 
for arg in args 
grep arg * */* */*/* */*/*/* */*/*/*/*; 
done 

,当我尝试运行它,这是发生了什么:

~/Work/richmond $ ./f.sh "\$_REQUEST\['a'\]" 
./f.sh: line 4: syntax error near unexpected token `grep' 
./f.sh: line 4: `  grep arg * */* */*/* */*/*/* */*/*/*/*;' 
~/Work/richmond $

我该怎么做这个正常吗?

而且,我认为一个更重要的问题是,我怎样才能让grep像这样通过子目录正确递归?

任何其他的提示和/或与shell脚本和一般使用bash的陷阱也将不胜感激。

+0

PS:你可以使用'for arg'来删除一行:这是'$ @'''中arg的快捷方式。 – l0b0 2011-09-19 12:59:41

回答

9

语法错误是因为您错过了do。至于递归搜索,如果你的grep-R选项,你会怎么做:

#!/bin/bash 
for arg in "[email protected]"; do 
    grep -R "$arg" * 
done 

否则,你可以使用find

#!/bin/bash 
for arg in "[email protected]"; do 
    find . -exec grep "$arg" {} + 
done 

在后一个例子,find将执行grep和更换{}大括号从当前目录.开始查找它找到的文件名。

(请注意,我也改变arg"$arg"。你需要的美元符号来获取变量的值,并引号告诉shell将它的值作为一个大的字,哪怕$arg包含空格或换行符。)

+0

这是完美的,谢谢 – 2009-10-02 21:07:22

+0

在迭代命令行参数时,您也可以省略“$ @”并将它写为“for arg; do ...” – Idelic 2009-10-03 05:10:52

3

在recusive grepping:

根据您的grep版本,你可以通过-R您grep命令,才能在搜寻递归(子目录中)。

1

最好的解决办法是如上所述,但是尽量把你的陈述在反勾:

`grep ...` 
+1

没有理由使用反引号(或首选'$()')在OP的脚本中或任何发布到目前为止的答案中。如果他将结果分配给一个变量或将其作为参数用于另一个命令,则情况会有所不同。 – 2009-10-02 21:48:23

1

你应该用“发现”加“xargs的”做文件搜索。

for arg in "[email protected]" 
do 
    find . -type f -print0 | xargs -0 grep "$arg" /dev/null 
done 

的“-print0”和“-0”选项假设你使用GNU grep,并确保该脚本工作,即使有空格或其他意外的字符在你的路径名。像这样使用xargs比使用find为每个文件执行它更有效率; /dev/null出现在参数列表中,因此grep总是报告包含匹配的文件的名称。

您可能会决定简化生活 - 也许 - 通过将所有搜索合并到一个使用egrepgrep -E。一次优化将捕获来自find的输出一次,然后在每次迭代中将其输出到xargs

0