Здесь я бы использовал sed
:
$ sed -n 's/^$[^_=]*_\([^=]*\)=.*drugs.*/\1/p' < file
bad
mixed
-n
в сочетании с флагом s
команды p
позволяет вывести только результат успешных замен.
С GNU grep
:
$ grep -Po '^[^=]*?_\K.*?(?==.*drugs)' < file
bad
mixed
Если вы хотите сделать drugs
переменной, то вы можете использовать:
string=drugs
grep -Po "^[^=]*?_\K.*?(?==.*$string)" < file
Однако обратите внимание, что если $string
содержит специальные символы в регулярном выражении, то в этом случае (с -P
) регулярные выражения, совместимые с Perl, придется экранировать (например, с string=". ..."
, которые будут соответствовать значениям, содержащим по крайней мере 3 символа, вместо значений, содержащих ...
). Эквивалент был бы еще хуже в sed
или awk
, так как неспособность экранировать их приведет к уязвимости инъекции команд (если содержимое $string
не находится под вашим полным контролем).
Используя awk
, вы можете сделать:
export STRING=drugs
awk -F = '(n = index($0, "=")) && \
(m = index($0, "_")) < n && \
index(substr($0, n+1), ENVIRON["STRING"]) {
print substr($0, m + 1, n - m - 1)
}' < file