sed -n 's/.*STRING:[[:blank:]]*\(..*\)/\1/p' filetest.txt
Вы бы не стали делать это в цикле оболочки, поскольку они, как правило, не идеальны для синтаксического анализа текста (см. " Почему использование цикла оболочки для обработки текста считается плохой практикой? " ).
Вместо этого приведенная выше единственная команда использует
sed
для сопоставления с регулярным выражением (, которое здесь переписано как базовое регулярное выражение , а не как PCRE, Perl-совместимое регулярное выражение). Команда редактирования, используемая сsed
, заменяет соответствующую строку захваченным текстом и выводит его.Другой способ:
awk -F ':[[:blank:]]*' '/STRING/ { print $2 }' filetest.txt
При этом каждая строка файла рассматривается как запись с полями, разделенными символом
:
, за которым следует любое количество пробелов или табуляций. При обнаружении шаблонаSTRING
в строке печатается второе такое поле.Вы все же хотели бы сделать это с петлей
bash
:while IFS= read -r line; do if [[ $line =~ 'STRING:'[[:blank:]]*(.+) ]]; then printf '%s\n' "${BASH_REMATCH[1]}" fi done
Массив
BASH_REMATCH
будет содержать различные захваченные биты совпадения.Само регулярное выражение (, которое должно быть расширенным регулярным выражением ), не должно заключаться в кавычки, за исключением битов, которые необходимо интерпретировать буквально. Примечание. :Здесь вы ошиблись; вы процитировали регулярное выражение и не искали захваченные данные вBASH_REMATCH
. Вы также пытались использовать регулярное выражение точно так, как вы бы написали выражение в Python.bash
не Python.Или,
while IFS= read -r line; do match=$(expr "$line" : '.*STRING:[[:blank:]]*\(..*\)') if [ -n "$match" ]; then printf '%s\n' "$match" fi done
Учитывая входные данные, которые вы указали в вопросе, все вышеперечисленные варианты будут выводить
"785c7208dcf0"
См. также: