私の.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" )
これにより、すべてが期待どおりに機能します。