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) был не так уж далек; использование grep -o
выведет только соответствующую подстроку:
$ subtext=$(egrep -o "\[[^]]*\]" <<<"$line")
... хотя это включает в себя скобки внутри захвата и, следовательно, не на 100% правильно.