Как обработать регулярное выражение после оценки (sed) - PullRequest
1 голос
/ 22 марта 2019

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

Например:

Если регулярное выражениеis: POS[AB]

и текст ввода: POSA_____POSB

Я хочу получить этот результат: P@O@S@A@_____P@O@S@B@

Пожалуйста, используйте sed или awk .

Я пробовал это:

$ echo "POSA_____POSB" | sed "s/POS[AB]/&@/g"

POSA@_____POSB@

$ echo "POSA_____POSB" | sed "s/./&@/g"

P@O@S@A@_@_@_@_@_@P@O@S@B@

Но мне нужно:

P@O@S@A@_____P@O@S@B@

Заранее спасибо.

С уважением, Октавио

Ответы [ 5 ]

1 голос
/ 22 марта 2019

Perl к результату!

perl -pe 's/(POS[AB])/$1 =~ s:(.):$1@:gr/ge'

/e интерпретирует замену как код и содержит другую замену, которая заменяет каждый символ на себя, плюс @.

InДревние Perls до 5.14 (т.е. без модификатора /r), вам нужно использовать немного более сложный

perl -pe 's/(POS[AB])/$x = $1; $x =~ s:(.):$1@:g; $x/ge'
0 голосов
/ 26 марта 2019

В данном примере вы можете использовать

echo "POSA_____POSB" | sed -r 's/POS([AB])/P@O@S@\1@/g'

Это не удастся для более сложных выражений.
Когда ваш ввод без \v и \r, вы можете использовать

echo "POSA_____POSB" | 
   sed -r 's/POS([AB])/\v&\r/g;  :loop;s/\v([^\r])/\1@\v/;t loop; s/[\v\r]//g'
0 голосов
/ 22 марта 2019

Вы можете заменить шаблон регулярного выражения, используя awk на sub (первая подходящая подстрока, sed "s///") или gsub (подстановка соответствующих подстрок глобально, sed "s///g") , Сами регулярные выражения не будут различаться между sed и awk. В вашем случае вы хотите:

Решение 1

РЕДАКТИРОВАТЬ: отредактировано в соответствии с комментариями

Следующая awk ограничит замену данной подстрокой (например, 'POSA _____ POSB'):

 echo "OOPS POSA_____POSB" | awk '{str="POSA_____POSB"}; {gsub(/[POSAB]/,"&@",str)}; {gsub(/'POSA_____POSB'/, str); print $0} '

Если ваш ввод состоит только из совпадающей строки, попробуйте следующее:

echo "POSA_____POSB" |  awk '{gsub(/[POSAB]/,"&@");}1'
Объяснение:

Отдельные '{}' для каждого действия и явные print для ясности.

gsub принимает 3 аргумента gsub(pattern, substitution [, target]), где target должен быть переменным (gsub изменит его на месте и сохранит результат там).

Мы используем var с именем 'str' и инициализируем его значением (вашей строкой) перед выполнением любых подстановок.

Второй gsub предназначен для помещения измененного str в $0 (соответствует всей записи / строке).

Выражения greedy по умолчанию --- они будут соответствовать самой длинной возможной строке.

[] вводит набор символов для сопоставления: каждый случай любого символа будет сопоставлен. Выражение выше говорит awk, чтобы соответствовать каждому вхождению любого из "POSAB".

Ваше первое регулярное выражение работает не так, как ожидалось, поскольку вы sed указали, что оно соответствует POS, оканчивающемуся на любое из [AB] (вся строка сразу). В другом выражении вы указали, что он соответствует любому отдельному символу (включая «_»), когда вы использовали: '.' (точка).

Если вы хотите обобщить это решение, вы можете использовать: [\w] выражение, которое будет соответствовать любому из [a-zA-Z0-9_] или [a-z], [A-Z], [0-9], чтобы соответствовать строчным, прописным буквам и цифрам соответственно.

Решение 2

Обратите внимание, что вы можете отрицать наборы символов с помощью [^], поэтому: [^_] также будет работать в этом конкретном случае.

Объяснение:

Отрицание означает: сопоставить что угодно, кроме символа между '[]'. Символ '^' должен быть первым символом, сразу после открытия '['.

Sidenotes:

Также может быть хорошей идеей напрямую указать, что вы хотите сопоставить один символ за раз с [POSAB]? или [POSAB]{1}.

Также обратите внимание, что в некоторых реализациях sed может потребоваться ключ -r для использования расширенных (более сложных) регулярных выражений.

0 голосов
/ 22 марта 2019

Попробуйте это регулярное выражение:

echo "POSA_____POSB" | sed "s/[A-Z]/&@/g"

Выход:

P@O@S@A@_____P@O@S@B@
0 голосов
/ 22 марта 2019

эхо "POSA_____POSB" | sed "s / [^ _] / & @ / g"

или

эхо "POSA_____POSB" | sed "s / [POSAB] / & @ / g"

...