私は次のパターンを使用してファイルを検索するのが好きです。
grep --color=auto -iRnHr --include={*.js,*.html,} --exclude-dir={release,dev,} "span" .
しかし、次のようにbashコマンドにこれを含めたいと思います。
findinfiles {*.js,*.html,} {release,dev,} "span" // syntax is just a guessing
$1
$2
このタイプの中かっこを bash 関数に渡し、などと一緒に使用する方法はわかりません。以下を使用する場合:
function findinfiles() {
echo $1, $2, $3
}
それから:
me@pc ~> findinfiles {*.js,*.html,} {release,dev,} "span"
*.js, *.html, release
もちろん、grepに引数を渡すことはこのようには機能しません。パラメーターが索引付けされているが正しくグループ化されていないようです。
この種の議論に対処する方法を教える人はいますか?
答え1
これを実行すると、findinfiles {*.js,*.html,} {release,dev,} "span"
次のことが発生します。
- Bashは引用符を解析し、コマンドを単語に分割します
findinfiles
。{*.js,*.html,}
{release,dev,}
span
- Bashは中括弧を展開して、、、、、、および
findinfiles
単語*.js
のリストを生成します。*.html
release
dev
span
- Bashはワイルドカードパターンを一致するファイル名のリスト
*.js
に展開します。*.html
どちらのパターンにも一致するファイル名がない場合は、そのまま残ります。 - Bashはnameを照会し、
findinfiles
それが関数であることを確認してから、指定された引数を使用して関数を実行します。
関数呼び出し時に中かっことワイルドカードの拡張を防ぐことができますが、中かっこは引数に文字通り表示されるため、特に便利ではありません。
関数呼び出しの形式を変更することをお勧めします。中かっこを使用しないでカンマのみを使用し、関数内で引数をカンマで手動で区切ります。
findinfiles () {
local patterns="$1" excludes="$2" pattern="$3"
shift 3
typeset -a cmd dirs
if [[ $# -eq 0 ]]; then dirs=(.); else dirs=("$@"); fi
cmd=(grep --color=auto -iRnHr)
local IFS=,
for x in $patterns; do
cmd+=("--include=$x")
done
for x in $excludes; do
cmd+=("--exclude-dir=$x")
done
"${cmd[@]}" "${dirs}"
}
説明する:
- 最初の3つのパラメータをローカル変数に保存します。追加の引数は検索するディレクトリです。
dirs
追加パラメータのリストに設定します。それ以外の場合.
(現在のディレクトリ)が使用されます。コンマに設定します
IFS
。スクリプト$patterns
に上記のように引用されていない変数拡張が含まれている場合、$excludes
シェルは次のことを行います。- 変数をその値に置き換えます。
- にある文字が含まれるたびに、変数を別の単語に分割します
IFS
。デフォルトでは、IFS
スペース文字(スペース、タブ、および改行)が含まれます。 - 各単語をワイルドカードパターンとして処理し、一致するファイルのリストに展開します。一致するファイルが存在しない場合、パターンは保持されます。
(これらの拡張手順を回避するには、
patterns="$1"
上記のスクリプトのように変数の置換に二重引用符を使用してください。)この関数は、配列変数で増分実行されるようにコマンドラインを作成します
cmd
。最後にコマンドが実行されます。
または、次の設定に基づいて構築することもできます。
shopt -s extglob globstar
fif_excludes='release dev'
alias fif='grep --color=auto -inH $fif_excludes'
次のコマンドを実行します。
fif span **/*.@(js|html)
説明する:
shopt -s extglob
または、@(js|html)
一致するワイルドカードパターンフォーマットを有効にします。 (このオプションは他のモード形式を有効にします。詳細についてはマニュアルを参照してください。)js
html
shopt -s globstar
すべての深さのサブディレクトリに一致するパターンを有効にします**/
(たとえば、再帰巡回を実行します)。- 除外リスト(頻繁には発生しないと予想される)を変更するには、
fif_excludes
変数を変更します。
答え2
bashは..{a,b,}1
に展開されますa1 b1 1
。
あなたのコマンドは次に拡張されますgrep --color=auto -iRnHr --include=*.js --include=*.html --include= --exclude-dir=release --exclude-dir=dev --exclude-dir= span
(jsファイルとhtmlファイルのないディレクトリ、そうでない場合はすべてのファイルが含まれます)。
パラメータを引用できますが、これは理想的ではないかもしれません... findinfiles "{*.js,*.html,}" "{release,dev,}" "span"
(それでもまだワイルドカードが必要です)
eval
これにより、次のバージョンのようにを使用して正しく拡張できます。
function findinfiles() {
eval "grep --color=auto -iRnHr --include=$1 --exclude-dir=$2 '$3'"
}