回答:
ksh93
そしてzsh
逆参照(又はより正確に有する1、交換に捕捉基への言及)サポート内部${var/pattern/replacement}
、ありませんbash
。
ksh93
:
$ var='Blah: -> r1-ae0-2 / [123]'
$ printf '%s\n' "${var/*@(->*([[:space:]])+([^[:space:]]))*/\1}"
-> r1-ae0-2
zsh
:
$ var='Blah: -> r1-ae0-2 / [123]'
$ set -o extendedglob
$ printf '%s\n' "${var/(#b)*(->[[:space:]]#[^[:space:]]##)*/$match[1]}"
-> r1-ae0-2
(mksh
manページでは、将来のバージョン${KSH_MATCH[1]}
では最初のキャプチャグループでサポートされることも記載されています。2017-04-25の時点ではまだ利用できません)。
ただし、ではbash
、次のことができます。
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
パターンが最初に見つかったことを確認するので、どちらが優れています。
システムの正規表現が\s
/をサポートしている\S
場合は、次のこともできます。
re='->\s*\S+'
[[ $var =~ $re ]]
を使用するとzsh
、PCREを最大限に活用できます。
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
でzsh -o extendedglob
、以下も参照してください:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
移植性:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
文字列にパターンの出現が複数ある場合、動作はそれらすべてのソリューションによって異なります。ただし、GNU grep
ベースのソリューションのように、それらのいずれも、すべての一致の改行区切りリストを提供しません。
そのためには、ループを手動で行う必要があります。たとえば、とbash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
を使用するとzsh
、この種のトリックを使用して、すべての一致を配列に格納できます。
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
1後方参照は、以前のグループで一致したものを参照するパターンをより一般的に指定します。たとえば、\(.\)\1
基本的な正規表現は、同じ文字が後に続く単一の文字と一致します(on aa
ではなくonに一致しab
ます)。これ\1
は\(.\)
、同じパターンのキャプチャグループへの後方参照です。
ksh93
ls -d -- @(?)\1
他のシェルではなく、そのパターンで後方参照をサポートします(たとえば、2つの同一の文字で構成されるファイル名をリストします)。標準のBREとPCREは後方参照をサポートしていますが、標準EREはサポートしていませんが、一部のERE実装では拡張としてサポートしています。bash
「S [[ foo =~ re ]]
のusesのEREを。
[[ aa =~ (.)\1 ]]
一致しませんが、
re='(.)\1'; [[ aa =~ $re ]]
システムのEREがサポートしている場合があります。
すべてのメッセージがとる正確な形式を知らない限り、これに確実に答えることは不可能です。ただし、一般的なアプローチとして、次を使用して特定のフィールドを印刷できますcut
。
$ cut -d ' ' -f 2 <<< '-> s7-Gi0-0-1:1-US / Foo'
s7-Gi0-0-1:1-US
または、次を使用してn番目の列ごとに印刷awk
できます。
$ awk -F' ' '{ for (i=2;i<=NF;i+=4) print $i }' <<< '-> r1-ae0-2 / [123], -> s7-Gi0-0-1:1-US / Foo'
r1-ae0-2
s7-Gi0-0-1:1-US