bashスクリプトを書くのは今回が初めてなので単純な間違いを犯しているかもしれません。
デフォルトでは、私はユーザーグループをインポートし、そのグループが特定のグループに属している場合は、それに応じて記録するスクリプトを作成しようとしています。明らかに、より多くの機能があるでしょうが、正規表現を機能させることができないときに機能を構築する必要はありません!
これまで私はこれを持っています:
#!/bin/bash
regex="^([a-zA-Z0-9\-_]+ : [a-zA-Z0-9\-_]+) (usergroup)$"
# example output
groups="username : username usergroup"
echo "$groups" >> /home/jrdn/log
if [[ "$groups" =~ $regex ]]; then
echo "Match!" >> /home/jrdn/log
else
echo "No match" >> /home/jrdn/log
fi
この正規表現を試してみたところで動作します。しかし、bashスクリプトでは$groups
、その後にのみ出力されますNo match
。それでは、何が起こっているのか教えてくれる人はいますか?
答え1
からman 7 regex
:
角かっこ式は「[]」で囲まれた文字のリストです。 …
...リテラル "-"を含めるには、最初または最後の文字で作成します。
正規表現にegrepを使用しようとするとエラーが発生します。
$ echo "username : username usergroup" | egrep "^([a-zA-Z0-9\-_]+ : [a-zA-Z0-9\-_]+) (usergroup)$"
egrep: Invalid range end
以下は、エラーが発生するより簡単なバージョンです。
$ echo 'hi' | egrep '[\-_]'
egrep: Invalid range end
特別ではないので、そうすべき\
範囲です。次のように最後に入力する必要があり[a-z]
ます。-
[_-]
echo "username : username usergroup" | egrep "^([a-zA-Z0-9_-]+ : [a-zA-Z0-9_-]+) (usergroup)$"
username : username usergroup
これはlibcバージョン(egrepまたはbash)に関係なく機能します。
編集する:これは実際にあなたの地域によって異なります。マンページではこれについて警告します。
範囲はコントロールの順序に大きく依存するため、移植可能なプログラムはそれに依存してはいけません。
たとえば、
$ echo '\_' | LC_ALL=en_US.UTF8 egrep '[\-_]'
egrep: Invalid range end
$ echo '\_' | LC_ALL=C egrep '[\-_]'
\_
もちろん、エラーが発生しなくても、必要に応じて実行されるわけではありません。
$ echo '\^_' | LC_ALL=C egrep '^[\-_]+$'
\^_
ASCIIで\
、、、[
を^
含む範囲です_
。
答え2
正規表現(およびより大きなフラグメントのバグ)の一般的な規則:段階的に切り取り、再構築するか、二分法を使用してください。どちらの方が良い方法を使用してください。
この場合、犯人は下線で明らかになりました。バックスラッシュを使用してエスケープするだけです。