BASH_REMATCH
シェルによって一致したグループを含む配列です。
$ line='Apr 12 19:24:17 PC_NMG kernel: sd 11:0:0:0: [sdf] Attached SCSI removable disk'
$ [[ $line =~ \[([^]]+)\] ]]; echo "${BASH_REMATCH[1]}"
sdf
これをループに入れたい場合は、それを行うことができます。例を次に示します。
while read -r line; do
if [[ $line =~ \[([^]]+)\] ]] ; then
drive="${BASH_REMATCH[1]}"
do_something_with "$drive"
fi
done < <(dmesg | egrep '\[([hsv]d[^]]+)\]')
このアプローチでは、外部呼び出しがループに入れられないため、シェルは、またはなどの外部プログラムを開始する必要がfork
ありません。そのため、ここで提供されている他のアプローチよりも間違いなく大幅にクリーンです。exec
sed
grep
ところで、最初のアプローチ (grep を使用) はそれほど遠くありませんでした。usinggrep -o
は、一致する部分文字列のみを出力します。
$ subtext=$(egrep -o "\[[^]]*\]" <<<"$line")
...ただし、これにはキャプチャ内の括弧が含まれるため、100% 正しいわけではありません。