引数リストを使用して他の関数を呼び出す関数は機能しません。

引数リストを使用して他の関数を呼び出す関数は機能しません。

私の.bash_aliasesは、次のようにコマンドラインで使用する関数を定義します。

search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/

この関数は結果を別のgrepコマンドにパイプするgrepコマンドを作成します(残念ながら以前のバージョンを使用しているため、これは複雑です)。

search() {
    local file_names opt OPTARG OPTIND pattern

    file_names=()
    while getopts ":n:" opt; do
        case $opt in
            n)
                file_names+=( "$OPTARG" )
                ;;
        esac
    done
    shift $((OPTIND-1))

    pattern="$1"
    shift

    if (( ${#file_names[@]} > 0 )); then
        file_names="${file_names[@]}"
        file_names=${file_names// /':\|'}:

        grep -I -r "$pattern" "$@" | grep "$file_names"
    else
        grep -I -r "$pattern" "$@"
    fi
}

この関数を呼び出すために別の関数を定義しました。

search-some-set-of-files() {
    local file_names directories

    file_names=( "-n page1.cshtml" "-n page2.cshtml" "-n page3.cshtml" )

    directories=( "/c/code/website/" "/c/stuff/something/whatever/" )

    search "${file_names[@]}" "$@" "${directories[@]}"
}

コマンドラインで、次のように関数を呼び出します。

search-some-set-of-files SomeTextIWantToSearchFor

何らかの理由で、結果には以下が含まれます。ファイルごとターゲットディレクトリに。つまり、私が指定したファイル名に基づいてgrepで結果がフィルタリングされません。

search-some-set-of-filesコマンドをエコーするように関数の最後の行を変更すると、次のような結果が得られます。

$ search-some-set-of-files SomeTextIWantToSearchFor
search -n .cs -n .cshtml -n .html SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/

これがまさに私が望むものです。このコマンドをコマンドラインにコピー(またはそのまま入力)すると、結果は元になります。

デバッグモード()を有効にすると、set -x各引数を個別に引用するシェルが表示されます。

$ search-some-set-of-files SomeTextIWantToSearchFor
+ search-some-set-of-files SomeTextIWantToSearchFor
+ local file_names directories
+ file_names=("-n page1.cshtml" "-n page2.cshtml" "-n page3.cshtml")
+ directories=("/c/code/website/" "/c/stuff/something/whatever/")
+ search '-n page1.cshtml' '-n page2.cshtml' '-n page3.cshtml' SomeTextIWantToSearchFor /c/code/website/ /c/stuff/something/whatever/
+ return
+ etc...

だから問題は、パラメータを関数に渡す方法だと思いますsearch。どうすれば解決できますか?

ベストアンサー1

あなたの質問は2番目の質問ですgrep

... | grep "$file_names"

-n関数を呼び出すと、ファイル名との間のスペース()が配列-n page1.cshtmlに含まれます。$file_names次に、次のものを交換します。

file_names=${file_names// /':\|'}:

:\|先頭の空白のため、文字列の先頭に追加内容が追加されます。したがって、2番目のgrepコマンドは実際には次のようになります。

... | grep ":\|page1.cshtml:\|page2.cshtml:\|page3.cshtml:"

結果、grep試合みんなすべての結果行には行が含まれ、filename:一致するためです:

したがって、簡単な解決策はスペースを削除することです。

file_names=( "-npage1.cshtml" "-npage2.cshtml" "-npage3.cshtml" )

これにより、すべてが期待どおりに機能します。

おすすめ記事