1

私は bash スクリプトの初心者で、次の問題があります。find および / または grep およびオプションのパラメーターを使用して、特定の文字列を含むファイルを検索できる検索スクリプトを作成しようとしています。最後の問題、すべての場合に条件に一致しない * 文字。

私のスクリプトには3つのパラメータがあります:

  • string_to_search (必須)
  • file_name_pattern (オプション)
  • パス (オプション)

例 :

./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(現在のdirtectoryに「a.txt」と「b.txt」という名前のファイルが2つしかないと仮定します)。「a.txt」は「*」ではないため、検索コードが実行されます。それを防ぐために私が知っている唯一の方法は、'あなたがしたようにアポストロフィ()で囲むか、バックスラッシュ( '\')でエスケープすることです

于 2012-04-05T17:28:00.810 に答える
3

を使用して、すべてのグロブ展開を無効にすることができます

 set -o noglob

その後*は特別ではありません:

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

ただし、スクリプトを呼び出す前にユーザーにこれを強制する方法はありません。スクリプトではなく、ユーザーのシェルがグロビングを制御するため、頼りになるものはありません。

あなたの唯一の選択肢は治療することです

./search_text.sh 'string_to_search' *

そっくり

./search_text.sh 'string_to_search' file1 file2

とにかくそういうことですから。

つまり、末尾のディレクトリが指定されて$1おらず、リテラルではない場合は大文字小文字*を使用しgrepます。

于 2012-04-05T17:32:58.847 に答える