我经常需要在文件中进行递归搜索。厌倦了一直输入整个“find/grep”组合,我刚刚创建了一个包含以下行的脚本:
find . -name $1 -exec grep $2 {} + 2>/dev/null
我的想法是,我应该能够以如下方式运行它,例如:
myfind '*' hello
问题是,当'*'
传递到脚本中时,脚本会将其扩展到目录中的每个文件。
我尝试引用一下$1
:
find . -name '$1' -exec grep $2 {} + 2>/dev/null
然而,这会$1
变成一个文字字符串。
非常感谢您能帮我找到正确的语法。我肯定遗漏了一些简单的东西。
答案1
我在这里演示了这个问题:
$ pie() { echo $1; }; pie '*'
1 2 3 4 5 file
扩大。厭扰。
但解决方案很简单。你只需要用 bash 能理解的方式引用它。我们使用双引号。它将被替换为变量内容,但不会被扩展。
$ pie() { echo "$1"; }; pie '*'
*
答案2
您需要熟悉有关 shell 变量扩展的基本规则。
NAME="start"
如果你将 $NAME 提供给 shell,它将被扩展为字符串开始
如果将字符串放在单引号中,则 shell 不会扩展单引号内的内容,因此 '$NAME' 仍为 $NAME
现在有了双引号,shell 将变量 $NAME 扩展为字符串开始但双引号会阻止所谓的文件通配。
您可能会问,文件通配是什么?
嗯,你做的
ls -l *
您期望 ls 命令列出所有文件。将 * 转换为目录中所有文件名的不是 ls,而是 shell。
现在假设你的目录中有一个名为 * 的文件,而你只想列出该文件,那么你可以使用
ls -l '*'
或者
ls -l "*"
单引号和双引号都会阻止 shell 将 * 扩展为文件列表。
也可以通过以下方式关闭通配符
set noglob
与其将这个简单的查找字符串作为一个单独的 shell 脚本,每次使用时都需要调用一个新的 shell,更有效的方法是将其创建为一个 shell 函数 fs(find_string)
function fs ()
{
\find . -type f -name "${1}" -exec egrep --color "${2}" {} /dev/null \;
}