1

我是 bash 脚本的新手,遇到以下问题:我正在尝试制作一个搜索脚本,让我可以使用 find 和/或 grep 以及可选参数搜索包含某个字符串的文件,但我被困住了最后一个问题,在所有情况下都不匹配条件的 * 字符。

我的脚本有 3 个参数:

  • string_to_search(必填)
  • 文件名模式(可选)
  • 路径(可选)

例子 :

./search_text.sh 'string_to_search' 'file_name_pattern' /path

我想得到以下内容:

  • 如果未指定 file_name_pattern 或为 *(带或不带引号)=> grep
  • 如果 file_name_pattern 不是 * 或 '*' => find + grep

这是我的代码:

#!/bin/bash

# ------------------------------------
# Set default values for optional parameters (tests)

if [ ! -z $2 ] 
then 
    FILE_TYPE=$2
    echo 'FILE_TYPE : var 2'
else
    FILE_TYPE="*"
    echo 'FILE_TYPE : *'
fi

if [ ! -z $3 ] 
then 
    LOCATION=$3
    echo 'LOCATION : var 3'
else
    LOCATION=.
    echo 'LOCATION : .'
fi

# ------------------------------------
# Do search / show conditions

if [ "$FILE_TYPE" == \* ];
  then 
    #grep -rn -C 0  --color=always  "$1" $LOCATION | less -R;
    echo ' => GREP';
  else
    #find $LOCATION -iname $FILE_TYPE | sort | xargs grep "$1" --color=always -n  2>/dev/null | less -R;
    echo '=> FIND';
fi

只需运行此代码以在最后显示 2 个回声以进行测试。

现在我的问题是:

./search_text.sh 'string_to_search' '*.php' /path  => works (FIND)
./search_text.sh 'string_to_search' '*' /path      => works (GREP)
./search_text.sh 'string_to_search' '*'            => works (GREP)
./search_text.sh 'string_to_search' *              => ERROR => goes to FIND INSTEAD OF GREP :-(
./search_text.sh 'string_to_search'                => works (GREP)

换句话说,我怎么能写出以下条件:

   if [ "$FILE_TYPE" == \* ];

这样在命令行中将这些值作为参数传递时,* 应该被视为与 '*' 相同吗?

即使用 \* 转义 * 当我们只将不带引号的 * 传递给脚本时,条件也不匹配。

换句话说,我想让 * 像在任何其他命令中一样被视为普通通配符,以便 * = '*'

非常感谢您的帮助!

4

2 回答 2

4

当你用*bash 编写时,它被解释为当前目录中的文件匹配。因此,您的脚本实际上被调用了./search_text.sh 'string_to_search' a.txt b.txt(假设当前目录中只有两个文件,名为“a.txt”和“b.txt”)。因为 'a.txt' 不是 '*',所以会执行您的查找代码。我知道防止它的唯一方法是用撇号(')括起来——就像你做的那样——或者用反斜杠('\')转义它

于 2012-04-05T17:28:00.810 回答
3

您可以使用禁用所有全局扩展

 set -o noglob

之后*并不特别:

$ ls *
ls: *: No such file or directory

但是,在调用您的脚本之前,没有办法强制您的用户执行此操作。由于用户的外壳,而不是您的脚本,控制 globbing 您没有追索权。

你唯一的选择是治疗

./search_text.sh 'string_to_search' *

完全一样

./search_text.sh 'string_to_search' file1 file2

反正就是这样。

换句话说,当没有指定尾随目录并且$1不是文字时*使用这种grep情况。

于 2012-04-05T17:32:58.847 回答