grepを使用して特定の拡張子と特定のディレクトリにあるファイルをフィルタリングするbashスクリプトがあります。スクリプトは次のとおりです。
generate_exclud_extensions() {
echo "\"(cpp$"
}
generate_exclude_dirs() {
echo "|^test)\""
}
command=$(generate_exclud_extensions)$(generate_exclude_dir)
echo $command
git ls-files | grep -vE $command
スクリプトは、cpp
拡張子を持つファイルとtest
ディレクトリの下のファイルをフィルタリングする必要があります。しかし、結果は最初の項目だけをフィルタリングし、2番目の項目は残しました。
事実 1:echo $command
出力"(cpp$|^test)"
し、端末で完全なコマンドを実行すると、git ls-files | grep -vE ""(cpp$|^test)""
正しい結果が得られました。
事実2:grepを次のように2回試しました。
git ls-files | grep -vE "cpp$" | grep -vE "^test"
Bashスクリプトでも同じエラーが発生しますが、端末で修正されました。
探していましたが、まだ運がありませんでした。誰もがこれについて明らかにすることができれば幸いです。
答え1
問題を再現できました。これは2つの機能のbashエスケープの問題です。この試み:
generate_exclude_extensions() {
echo '(cpp$'
}
generate_exclude_dirs() {
echo '|^test)'
}
command=$(generate_exclude_extensions)$(generate_exclude_dirs)
echo "$command"
git ls-files | grep -vEe "$command"
再現したいコード
generate_exclude_extensions() {
echo '(cpp$'
}
generate_exclude_dirs() {
echo '|^test)'
}
command=$(generate_exclude_extensions)$(generate_exclude_dirs)
echo "$command"
echo -e 'cpp\n
test\n
test456\n
display?5\n' | grep -vEe "$command"
スクリプトに2つのタイプミスがあります
generate_exclude_dir -> generate_exclude_dirs
generate_exclud_extensions -> generate_exclude_extensions
:) 楽しくお過ごしください
答え2
別のアプローチは次のとおりです。
generate_exclude_extensions() {
echo 'cpp$'
}
generate_exclude_dirs() {
echo '^test'
}
exclusions=$(
generate_exclude_extensions
generate_exclude_dir
)
printf '%s\n' "$exclusions"
git ls-files | grep -ve "$exclusions"
つまり、1行に1つの除外項目がある場合-E
。
答え3
Gitを使用できますexclude
パス指定フィルタ出力:
exclude_extensions=( '*cpp' '*.txt' ) # added `*.txt` as sample file extension
exclude_dirs=( 'test/*' ) # exclude files in relative directory `test`
git ls-files "${exclude_extensions[@]/#/:(exclude)}" "${exclude_dirs[@]/#/:(exclude)}"
パラメータ拡張は、"${exclude_...[@]/#/:(exclude)}"
接頭辞付きの空白で区切られた項目の配列と、その後にパス指定:(
"magic word"が続く配列に拡張されます。exclude
)
結果のコマンドは次のとおりです。
git ls-files ':(exclude)*cpp' ':(exclude)*.txt' ':(exclude)test/*'