Удалите какой-либо символ в начале и в конце, используя sed

#regex #awk #sed #grep

Вопрос:

Я пытаюсь извлечь слово между "profile " и "]" .

мое содержимое

 [profile gateway]
[profile personal]
[profile DA]
[profile CX]
 

для этого я старался

 less ~/.aws/config |grep  "[profile"|sed  -E 's/[profile(.)//'
 

что дает

 gateway]
personal]
DA]
CX]
 

Я знаю, что могу добавить канал и использовать tr для удаления последнего "]" или даже вырезать, но может ли кто-нибудь помочь мне с приведенной выше командой sed с регулярным выражением для удаления последнего "]"

Комментарии:

1. Я уверен, что существует гораздо более эффективное/сложное решение, но вы можете попробовать использовать 3 команды sed в одной: sed -E 's/[//;s/]//;s/profile //'

Ответ №1:

Вы можете использовать sed :

 sed -n 's/.*[profile *([^][]*).*/1/p' ~/.aws/config
 

Подробные сведения:

  • -n — подавить вывод строки по умолчанию
  • .*[profile *([^][]*).*/ — найдите любой текст, [profile , ноль или более пробелов, затем выделите в группу 1 любые ноль или более символов , отличных от [ и ] , а затем сопоставьте остальной текст
  • 1 — заменить значением группы 1
  • p — выведите результат подстановки.

Смотрите онлайн-демонстрацию:

 s='[profile gateway]
[profile personal]
[profile DA]
[profile CX]'
sed -n 's/.*[profile *([^][]*).*/1/p' <<< "$s"
 

Выход:

 gateway
personal
DA
CX
 

С помощью GNU grep

 grep -oP '(?<=[profile )[^]] ' ~/.aws/config
 

Регулярное (?<=[profile )[^]] выражение соответствует местоположению, которому непосредственно предшествует profile строка, а затем соответствует одному или нескольким символам, отличным от ] . -o опция позволяет grep извлекать только совпадения и P включает синтаксис регулярных выражений PCRE.

С awk

Вы также можете использовать awk :

 awk '/^[profile .*]$/{print substr($2, 0, length($2)-1)}' ~/.aws/config
 

Он найдет все строки , которые начинаются с [profile , и введет второе поле без последнего символа (то есть ] символ, который будет опущен).

Ответ №2:

Если вы можете использовать grep с -P для регулярного выражения, совместимого с Perl:

 less ~/.aws/config | grep -oP  "[profile K[^][] (?=])"
 

Шаблон совпадает:

  • [profile Совпадение буквально
  • K Забудьте, что соответствует до сих пор
  • [^][] Сопоставьте 1 раз любой символ, кроме [ и ]
  • (?=]) Положительный внешний вид для утверждения (не совпадает) ]

Для содержимого примера выходные данные будут

 gateway
personal
DA
CX
 

Ответ №3:

Сделайте это просто awk ; сделайте разделители полей как [profile ИЛИ ] (в соответствии с показанными образцами) и распечатайте столбцы в соответствии с необходимыми выводами.

 awk -F'\[profile |\]' '{print $2}' Input_file
 

Ответ №4:

— — извлечение слова между profile и ] означает удаление до profile и после ] , т. е. ^.*profile и ].*$ :

 $ sed 's/^.*profile |].*$//g' file
 

Выход:

 gateway
personal
DA
CX
 

Обратите внимание, что если найдена только одна граница, она удаляется.

Ответ №5:

Еще одно более короткое awk решение:

 awk -F '[] ]' '$1 == "[profile" {print $2}' ~/.aws/config

gateway
personal
DA
CX
 

Ответ №6:

trying to extract word between "profile " and "]"

Также с awk использованием в качестве условия, которое profile находится в конце $1 :

 awk '$1 ~ /profile$/ {sub(/]$/,"",$2);print $2}' file
gateway
personal
DA
CX