Если ваш grep
поддерживает PCRE, вы можете:
grep -Po '^Hello \K[^ ]+(?= )' hi.html
Чтобы сохраните его в переменной:
myvariable="$(grep -Po '^Hello \K[^ ]+(?= )' hi.html)"
Альтернативный sed
способ:
sed -n 's/^Hello \([^ ]\+\) .*/\1/p' hi.html
Чтобы сохранить его в myvariable
:
myvariable="$(sed -n 's/^Hello \([^ ]\+\) .*/\1/p' hi.html)"
Обратите внимание, что синтаксический анализ HTML с использованием Regex может быть не очень хорошей идеей.
Вы должны удалить \
перед :
во втором тесте, иначе он попытается сопоставить буквальный символ \
.
Это не совпадения с регулярными выражениями, которые вы выполняете, а соответствия шаблону подстановки оболочки (точно так же, как в командной строке, когда вы используете *
в шаблонах ). Это не имеет большого значения в данном случае.
Я предполагаю, что вы хотели бы извлечь 20 из двух первых строк и сохранить их в devReadErr
, но не тогда, когда строка читается как READ: DISABLED
. Это именно то, что делает ваш код, если удалить \
:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $2}')
fi
Другой способ сделать то же самое:
if [[ "$line" != *'DISABLED' ]]; then
devReadErr=${line##* }
fi
Это извлекает число как строку после последнего символа пробела в $line
, если строка не заканчивается словом DISABLED
. Это позволяет избежать echo
и awk
.
Если это часть более крупного цикла, который анализирует файл построчно, то я бы предложил написать его на awk
или другом языке, предназначенном для анализа текста. См., например, Почему использование цикла оболочки для обработки текста считается плохой практикой? .
Я подозреваю, что ты хочешь:
if [[ $line = *RAW_READ_ERROR_RATE* ||
$line = READ:* && $line != *"READ: DISABLED"* ]]; then
Оператор&&
[[...]]
имеет приоритет над ||
, но оператор оболочки&&
имеет тот же приоритет, что и ||
.
Или сделать это явным:
if [[ $line = *RAW_READ_ERROR_RATE* ||
($line = READ:* && $line != *"READ: DISABLED"*) ]]; then
Или используя операторы оболочки &&
/ ||
и несколько [[...]]
s:
if [[ $line = *RAW_READ_ERROR_RATE* ]] || {
[[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]]; }; then
Или изменить порядок:
if [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]] ||
[[ $line = *RAW_READ_ERROR_RATE* ]]; then
Или используйте шаблон, который соответствует всем:
if [[ $line = @(*RAW_READ_ERROR_RATE*|!(!(*READ:*)|*READ:\ DISABLED*)) ]]; then
Без скобок/фигурных скобок ваше читается как:
if [[ ($line = *RAW_READ_ERROR_RATE* ||
$line = READ:*) && $line != *"READ: DISABLED"* ]]; then
Это не должно мешать ему сопоставлять строки, содержащие RAW_READ_ERROR_RATE
, но при условии, что они не содержат READ: DISABLED
.