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 <filetest.txt
Массив 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 <filetest.txt
Учитывая входные данные, которые вы указали в вопросе, все вышеперечисленные варианты будут выводить
"785c7208dcf0"
См. также: