1

我正在尝试编写一个 bash shell 脚本(这是我没有太多经验的东西)来在我通过 ssh 操作的 Unix 机器上搜索 C 代码。

这是我脚本中的代码:

#! /bin/bash

find . \( -name '*.c' -o -name '*.h' \) -exec grep -n '<SEARCH_STRING>' {} + | sed -e "s/^\(\..*\.c\):\([0-9]*\):[ \t]*\(.*\)$/\1 :: \2\n\3\n/" | sed -e "s/^\(\..*\.h\):\([0-9]*\):[ \t]*\(.*\)$/\1 :: \2\n\3\n/" | sed ''/<SEARCH_STRING>/s//`printf "\033[31m<SEARCH_STRING>\033[0m"`/'' | less -R

请注意,这只是我用来表示我的搜索字符串的东西,当然我实际上并不是在逐字搜索。

我意识到这有几个问题。首先,当我在命令行中键入底线(没有 #!/bin/bash 标头的“脚本”)时,它实际上工作得很好,并给了我想要的结果。我知道在将其转换为 bash 脚本时应该转义某些字符,但我尝试转义几个(组合)字符,它总是给我同样的错误:

find: missing argument to `-exec'
./code_search.sh: line 4: <SEARCH_STRING>: command not found
sed: -e expression #1, char 43: unterminated `s' command
printf: usage: printf [-v var] format [arguments]
./code_search.sh: line 8: \033[31m<SEARCH_STRING>\033[0m: command not found
sed: -e expression #1, char 46: unterminated `s' command

另外,我意识到我不应该将搜索字符串硬编码到我的脚本中,因为将搜索字符串作为参数提供给脚本要方便得多,但我真的不知道该怎么做。

正如我所说,我没有太多编写 bash 脚本的经验,我尝试编写这个脚本来帮助我完成编码工作。但是,我不能再花时间调试这个了,因为这不是我的老板付钱给我做的。我问过我的同事,但他们也没有一个能帮助我。

我知道自己不花很多精力去学习更多关于 bash shell 脚本的知识有点便宜,但就像我说的那样,我真的不能抽出时间。谁能帮我完成这个脚本?

提前非常感谢!

4

2 回答 2

0

这样它不会给出任何错误。

#! /bin/bash

searchstring=$1

find . \( -name '*.c' -o -name '*.h' \) -exec grep -n "$searchstring" {} + \ 
        | sed -e "s/^\(\..*\.c\):\([0-9]*\):[ \t]*\(.*\)$/\1 :: \2\n\3\n/" \
        | sed -e "s/^\(\..*\.h\):\([0-9]*\):[ \t]*\(.*\)$/\1 :: \2\n\3\n/" \
        | sed ''/"$searchstring"/s//`printf "\033[31m""$searchstring""\033[0m"`/'' \
        | less -R

但是,这并不意味着它有效。如果没有一些示例输入和所需的输出,就不可能为您提供进一步的帮助。例如,第三个sed对我来说似乎是错误的。

于 2012-10-04T08:58:04.527 回答
0

这是因为,在最后一个 sed 命令中,字符 < 没有转义:双单引号仅表示空字符串 ''; < 被解释为文件重定向,shell 尝试从文件“SEARCH_STRING”中读取。

sed ''/<SEARCH_STRING>/s//`printf "\033[31m<SEARCH_STRING>\033[0m"`/'' 

应该改为

sed '/<SEARCH_STRING>/s//'`printf "\033[31m<SEARCH_STRING>\033[0m"`'/' 

此外,在出现错误之后,查找版本可能不支持命令末尾的 + man find,在这种情况下,+ 功能可以由 xargs 完成(但如果文件名可以包含空格,这可能会失败)

find . \( ... \) | xargs grep -n '<SEARCH_STRING>'
于 2012-10-04T09:33:49.183 回答