たとえば、Shell変数があります。 a = "大きな小さな男"。 bashで正規表現を使用して変数を真ん中の単語だけを大文字にして出力するにはどうすればよいですか? (大きな小さな男)
変数を3つの変数に分離し、それらをエコーで展開することでそれを行うことができます。たとえばfirst=${a%* }
など。しかし、1つの正規表現で1つのシングルゴーにするにはどうすればよいですか。
一行でそれを行うことは可能ですか?大文字の演算子を使用する(^)
sed
GNU sed:を使用していると仮定します。
$ sed -E 's/(\w+) (\w+) (\w+)/\1 \U\2\E \3/' <<< 'big little man'
big LITTLE man
このコマンドは、 GNU固有のシーケンス\U
および\E
を使用して、後続の文字をそれぞれ大文字に変換し、大文字と小文字の変換をキャンセルします。
awk
正規表現を操作していませんが、awk
は、単一の単語を大文字にする別の便利な方法を提供します。
$ awk '{print($1, toupper($2), $3)}' <<< 'big little man'
big LITTLE man
bash
Bash自体には正規表現ベースの変換はありませんが、文字列を配列として扱うことで部分大文字化を実現できます。
$ (read -a words; echo "${words[0]} ${words[1]^^} ${words[2]}") <<< 'big little man'
big LITTLE man
ここで、^^
は、配列の2番目の要素(つまり、2番目のWord)を大文字に変換します。この機能はBash 4で導入されました。
bash
拡張演算子で一度に実行できるとは思いません。 zsh
でできます:
_set -o extendedglob # for (#m)
b=${a/(#m) * /${(U)MATCH}}
_
または:
_b=${(S)a/(#b)(*) (*) (*)/$match[1] ${(U)match[2]} $match[3]}
_
どこ:
(#m)
_により、一致した文字列が_$MATCH
_で使用可能になります(#b)
_は後方参照を有効にします${(U)var}
(また__$var:u
_)は大文字になります(bash
の_${var^^pattern}
_より数十年前)。(S)
_は貪欲でないマッチングをオンにします。リクエストに応じて、${variable^^}
を使用してbash
で1行に実行します。
$ a="big little man"
$ [[ "$a" =~ ^([^ ]+)\ ([^ ]+)\ (.*) ]] && a="${BASH_REMATCH[1]} ${BASH_REMATCH[2]^^} ${BASH_REMATCH[3]}"
$ echo "$a"
big LITTLE man
これは、正規表現([^ ]+)\ ([^ ]+)\ (.*)
を$a
の文字列と照合します。一致する場合は、スペースで区切られた3つのサブストリングが含まれます。最初と2番目の部分文字列はスペースを含まない任意の文字列であり、3番目の部分文字列は文字列の残りのビットになります。
式が一致した場合、$a
の値は、大文字の2番目の部分文字列で書き換えられます。
これは、元の文字列がスペース以外の文字で始まることを前提としています。