前者Get-ChildItem
とSelect-String
後者の使用を標準化するためにPowerShellとBashスクリプトを作成していますgrep
。
Bashスクリプトの一部としてコマンドライン引数を使用して(を含むカンマ区切りのファイル名の値を解析します)。複数形)これをGrepに伝えようとしましたが、--include=
いくつかの困難に遭遇しました。
最初は中かっこ拡張を試してみましたが、(1)正しく動作しなかったこと、(2)grepは技術的にこれをサポートしていません。とにかく複数が含まれています。
これで、正常に処理された複数のインクルードを使用しようとしていますが、値にスペースが含まれていない場合にのみその値が引用符で囲まれていないため、スクリプトは何もしません$grepstring
。シェルのコピーと貼り付けの出力は正しく機能しますが、引用されたバージョンを機能させることはできません。
以下はスクリプトの単純化されたバージョンです。
#!/bin/bash
include="$1"
if [[ $include == *","* ]]; then
IFS=',' read -r -a includearray <<< "$include"
includemulti=""
firstloop="yes"
for element in "${includearray[@]}"
do
# Trim leading and trailing whitespace
element="${element## }"
element="${element%% }"
if [[ "$firstloop" == "yes" ]]; then
firstloop="no"
includemulti+="--include=$element"
# includemulti+="--include=\"$element\""
# includemulti+="--include='"$element"'"
# includemulti+='--include="'$element'"'
# includemulti+='--include="'"$element"'"'
# includemulti+="--include='$element'"
else
includemulti+=" --include=$element"
# includemulti+=" --include=\"$element\""
# includemulti+=" --include='"$element"'"
# includemulti+=' --include="'$element'"'
# includemulti+=' --include="'"$element"'"'
# includemulti+=" --include='$element'"
fi
done
grep -ERins $includemulti "<pattern>" "<path>"
grepstring="grep -ERins $includemulti \"<pattern>\" \"<path>\""
echo $grepstring
else
grep -ERins --include="$include" "<pattern>" "<path>"
fi
効率的な:
bash ~/test.sh 'Hello*.txt, *.sh'
bash ~/test.sh 'Hello W*.txt'
動作しません:
bash ~/test.sh 'Hello W*.txt, *.sh'
何度も呼び出す方が簡単かどうか疑問になり始めました。grep
各呼び出しには以下が含まれます。
ベストアンサー1
分析する
入力が次の場合、'Hello W*.txt, *.sh'
スペースは区切り文字として使用されます。だからあなたはincludemulti
3つの単語に分けられます:
--include=Hello
W*.txt
--include=*.sh
set -x
コマンドの前にスクリプトを追加すると、スクリプトがどのようにgrep
実行されるかを正確に確認でき、私が言ったことを確認できます。
+ grep -ERins --include=Hello 'W*.txt' '--include=*.sh' <pattern> <path>
行を変更しincludemulti+=
て要素の周りに引用符を追加しても、次のようになります。
includemulti+=" --include=\"$element\""
bash
スペースはまだ単語の区切り文字として使用されるため、役に立ちません。
+ grep -ERins '--include="Hello' 'W*.txt"' '--include="*.sh"' <pattern> <path>
ソリューション1
スクリプトを変更しなくてはならない解決策の1つは、要素の周りに引用符を追加することです。そしてeval
コマンドの前に組み込みコマンドを追加しますgrep
。bash
マニュアルページから:
評価する[アルギニン...]
これパラメータ読んで一緒に接続してコマンドを形成します。その後、コマンドはシェルから読み取られ実行され、終了ステータスは次のように返されます。評価する。もしなければパラメータ、またはちょうど空のパラメータ、評価する0を返します。
eval
したがって、grepコマンドの前に追加すると、実際には次のようになります。
bash -c 'grep -ERins --include="Hello W*.txt" --include="*.sh" <pattern> <path>'
set -x
コマンドの前にはgrep
2行が表示され、2行目は実際に実行される行です。
+ eval grep -ERins '--include="Hello' 'W*.txt"' '--include="*.sh"' <pattern> <path>
++ grep -ERins '--include=Hello W*.txt' '--include=*.sh' <pattern> <path>
ソリューション2
これはよりエレガントなソリューションです。繰り返すのではなく、配列変数を変更できますincludearray
。
# Remove leading space from every element in the array
includearray=("${includearray[@]## }")
# Remove trailing space from every element in the array
includearray=("${includearray[@]%% }")
# Add --include= as the prefix of every element in the array
includearray=("${includearray[@]/#/--include=}")
その後、grep
コマンドは次のようになります。
grep -ERins "${includearray[@]}" <pattern> <path>
includearray
これにより、配列内の各要素がスペースの数に関係なく単一の単語として扱われるため、要素を引用符で囲む必要がなくなります。
最終コードは次のとおりです。
#!/bin/bash
include="$1"
if [[ $include == *","* ]]; then
IFS=',' read -r -a includearray <<< "$include"
# Remove leading space from every element in the array
includearray=("${includearray[@]## }")
# Remove trailing space from every element in the array
includearray=("${includearray[@]%% }")
# Add --include= as the prefix of every element in the array
includearray=("${includearray[@]/#/--include=}")
grep -ERins "${includearray[@]}" "<pattern>" "<path>"
else
grep -ERins --include="$include" "<pattern>" "<path>"
fi