Bashスクリプトの正規表現

Bashスクリプトの正規表現

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で\、、、[^含む範囲です_

おすすめ記事