извлечь строку в фигурных скобках после соответствующего текста и сохранить в качестве переменной - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть несколько строк в моем файле, как показано ниже

DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('SUN') NAME('CAT') TRASMIT('TRUCK') REPLACE

Текст в скобках изменяется для каждой строки.Я пытаюсь извлечь текст в скобках после MANAGER (в данном случае SUN), сохранить его как переменную и заменить на planet.SUN.star.

Я попытался использовать разделитель полей awk для извлечения текста между скобками сразделитель полей в виде скобок, но я мои результаты не согласуются.Иногда я не получаю текст в скобках после соответствующего слова МЕНЕДЖЕР.

Желание выводится как ниже

 DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('PLANET.SUN.STAR') NAME('CAT') TRASMIT('TRUCK') REPLACE

Ответы [ 3 ]

0 голосов
/ 19 декабря 2018

Если Perl - ваш вариант, попробуйте:

word="MANAGER"
replacement="PLANET.SUN.STAR"
perl -pe "s/(?<=${word}\(')(.+?)(?='\))/${replacement}/" <<< "DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('SUN') NAME('CAT') TRASMIT('TRUCK') REPLACE"

, который выдает:

DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('PLANET.SUN.STAR') NAME('CAT') TRASMIT('TRUCK') REPLACE
  • Регулярное выражение (?<=${word}\(') - это утверждение, которое нужно сопоставить1010 *.
  • Регулярное выражение (?='\))/ является предварительным утверждением, совпадающим с ').
  • Регулярное выражение (.+?) между ними является шаблоном, подлежащим замене.

Не думаю, что вам нужно присваивать SUN переменную только для целей замены, но если вам это нужно, изменение кода легко.

EDIT

Вот обновленная версия с предположением о требовании OP.

perl -pe "s/(?<=MANAGER\(')(.+?)(?='\))/PLANET.\$1.STAR/" text

Входной текст:

DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('SUN') NAME('CAT') TRASMIT('TRUCK') REPLACE
DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('MOON') NAME('CAT') TRASMIT('TRUCK') REPLACE
DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('JUPITER') NAME('CAT') TRASMIT('TRUCK') REPLACE

Вывод:

DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('PLANET.SUN.STAR') NAME('CAT') TRASMIT('TRUCK') REPLACE
DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('PLANET.MOON.STAR') NAME('CAT') TRASMIT('TRUCK') REPLACE
DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('PLANET.JUPITER.STAR') NAME('CAT') TRASMIT('TRUCK') REPLACE
  • Прежде всего, давайте сосредоточимся на части MANAGER('blah') и разделим строку на три части: MANAGER(', blah и ').
  • Регулярное выражение (?<=MANAGER\(') соответствует 1-мукусок.Регулярное выражение (?<=pattern) называется положительным взглядом нулевой ширины за утверждением .Он работает как якорь , а соответствующая строка не включена в группу захвата.Природа полезна для повторного использования исходной подстроки (1-й кусок) без влияния.
  • Регулярное выражение (?='\)) соответствует 3-му элементу.Регулярное выражение (?=pattern) является положительным утверждением нулевой ширины , которое аналогично 1-му.
  • Регулярное выражение (.+?) соответствует подстроке, окруженной 1-м регулярным и 3-модин.? после квантификатора + вызывает кратчайшее совпадение , в противном случае регулярное выражение будет пытаться найти максимально возможное совпадение за границами слова.
  • Новое, давайте перейдем к ЗАМЕНЕчасть.Мы хотим добавить PLANET. перед захваченным словом и добавить .STAR после слова.Захваченное слово можно отнести к $1, тогда запасная часть будет выглядеть как PLANET.\$1.STAR.Обратная косая черта необходима, потому что скрипт находится в двойных кавычках.

В качестве альтернативы приведена версия AWK, которая дает тот же результат:

awk -v q=\' '$0=gensub("(MANAGER\\(" q ")([^" q "]+)(" q "\\))", "\\1PLANET.\\2.STAR\\3", "g")' text

Надеюсь, что это соответствует требованию.

0 голосов
/ 19 декабря 2018

Это довольно тривиально с sed и использованием группы захвата и обратная ссылка с использованием стандартной формы замены sed "s/find/replace/", где find содержит группу захвата"MANAGER('\(.[^']*\)': и replace использует обратную ссылку \1 для вставки захваченного, например,

sed "s/MANAGER('\(.[^']*\)')/MANAGER('PLANET.\1.STAR')/"

В вашем примере вы получите:

$ echo "DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('SUN') NAME('CAT') TRASMIT('TRUCK') REPLACE" | \
sed "s/MANAGER('\(.[^']*\)')/MANAGER('PLANET.\1.STAR')/"
DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('PLANET.SUN.STAR') NAME('CAT') TRASMIT('TRUCK') REPLACE

Чтобы захватить "SUN" в переменной, вы можете использовать подстановку команд вместе с grep -o и аналогичное регулярное выражение, за которым следуют расширения параметра для обрезки внешнего одиночногокавычки, например

var=$(echo "your_string" | grep -o "MANAGER('.[^']*')")
var="${var#*\'}"
var="${var%\'*}"
echo "var: $var"

Результаты в выводе:

var: SUN
0 голосов
/ 19 декабря 2018

Решение с awk:

echo "DEF QR('xxx.yyy.sss') USE(YES) DESC('Something') MANAGER('SUN') NAME('CAT') TRASMIT('TRUCK') REPLACE" \
| awk '{
    # Look for the field starting with MANAGER(
    for ( I=1 ; I <= NF ; I++ ) {
      if ( $I ~ /^MANAGER[(]/ ){
        MANAGER = $I
        break
      }
    }

    # Remove everything except our value
    sub( /^MANAGER[(]\x27/, "", MANAGER )
    sub( /\x27[)]$/, "", MANAGER )

    # Rebuild the line with the new value
    $I = "MANAGER(\x27PLANET." MANAGER ".STAR\x27)"
    print
  }'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...