我怎样才能让这个命令在 bash 脚本中工作?

我怎样才能让这个命令在 bash 脚本中工作?

这是一个在命令行上非常适合我的命令:

find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;

当我运行上述命令并将搜索路径替换为任何路径时,该命令仍然仅显示具有或扩展名.的文件列表。.c.h

现在,我想编写一个简单的 bash 脚本,使用与变量值相同的命令,这样我就可以通过较小的修改来执行脚本来执行类似的搜索,而不必重新键入命令。但这就是我遇到逃脱规则噩梦的地方(或者缺乏对它的正确理解!)。

我写了一个脚本,如下所示:

#!/bin/bash

path="/home/vinod"
string="somestring"

command="find ${path} -type f -exec grep -Hin --include=*.h  --include=*.c '${string}' {} \;"

echo $command

$command

当我运行上面的脚本时,命令回显两次而不是一次,如下所示

find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;
find . -type f -exec grep -Hin --include=*.h --include=*.c 'somestring' {} \;

以及以下运行时错误:

find: missing argument to -exec

从 echo 中可以看出,该命令与我在命令行上运行它时的命令完全相同,我得到了预期的结果。

对我的脚本可能有什么问题有什么想法吗?

TIA

答案1

不要使用变量来存储命令。相反,使用变量来存储数据并使用函数来存储(定义)命令。

我们可以创建一个带有两个参数的命令:起始搜索路径和搜索字符串。

如果您的起始搜索路径也是固定的,您可以简单地修改它以仅采用搜索模式。事实上,让我们颠倒参数的顺序,如果省略搜索路径,则默认为您的$HOME目录:

#!/bin/sh
# Search in *.c and *.h files for a matching pattern
#
pattern=$1
path=${2:-$HOME}

find "${path:-.}" -type f \( -name '*.c' -o -name '*.h' \) -exec grep -Hin -- "$pattern" {} +

将其保存为文件chfind,使其可执行(chmod a+rx chfind),然后将其放在$PATH.您现在可以像任何其他实用程序一样使用它:

chfind 'main'
chfind 'main' /some/other/tree/of/files

因为我们没有使用grep -F搜索字符串实际上是正则表达式而不是普通字符串,所以搜索诸如这样的声明FILE *fp将不起作用。

最后,如果您希望路径名相对于您的搜索路径,您可以将目录更改为$path,然后从那里搜索:

cd "$path" &&
    find -- * -type f \( -name '*.c' -o -name '*.h' \) -exec grep -Hin -- "$pattern" {} +

可能值得解释一下如何通过函数而不是在脚本中内嵌来实现这一点。我已经解决了您的基本要求(“我想编写一个简单的 bash 脚本 [...],以便我可以执行脚本 [...] 进行类似的搜索,而不必重新输入命令”)。但是如果你想使用一个函数,它几乎是完全一样的:

#!/bin/bash
# Search in *.c and *.h files for a matching pattern
#
chFind() {
    local pattern=$1 path=$2

    find "${path:-.}" -type f \( -name '*.c' -o -name '*.h' \) -exec grep -Hin -- "$pattern" {} +
}

chFind "$1" "${2:-$HOME}"

相关内容