замена на основе положения / смещения

#perl #awk #sed

#perl #awk #sed

Вопрос:

Я хотел заменить текст с позиции 11 на 18 некоторым текстом xxxxxxxxxx

Пример: 0123456789abcdeg123456efsgtext1234500th23sdfksbfk

в приведенной выше строке мой скрипт заменяет abcdeg1 (позиции с 11 по 18) на xxxxxxxx для этого я использую приведенный ниже скрипт perl -pe ‘s/^(.{10}).{8}/$ 1xxxxxxxxxxxxxxxxxxx/’ awktest.2019 > awktest.2019masked.txt

теперь проблема в том, что он заменяет место в каждой строке, даже если оно пустое в этих позициях (с 11 по 18)

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

perl -pe ‘s/^(.{10}).{8}/$ 1xxxxxxxxxxxxxxxxxxx/’ awktest.2019 > awktest.2019masked.txt

любая помощь приветствуется, заранее спасибо

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

1. Пожалуйста, заверните ваши образцы в КОДОВЫЕ ТЕГИ и затем дайте нам знать.

2. Пожалуйста, опишите, что должно произойти, когда длина строки составляет менее 18 символов. Вы говорите «даже если оно пустое» и «только захваченная группа не равна нулю», что кажется противоречивым. Добавьте пример.

Ответ №1:

Из вашего описания следует, что замена уже произошла в строках, которые вы определили как null в позиции 11-18, поэтому есть по крайней мере 8 совпадающих символов, но, вероятно, они вам не видны. скорее всего, это просто пробелы. Если это так, вы можете просто добавить положительный ориентир в свой шаблон, чтобы убедиться, что в следующих 8 символах есть хотя бы один пробел, не содержащий пробелов:

 perl -lpe 's/^(.{10})(?=.{0,7}S).{8}/$1xxxxxxxxxxxxxxxxx/' file
  

В добавленном подшаблоне (?=.{0,7}S) :

  • (?=...) является положительным ориентиром, который не использует символы при сопоставлении и может служить в качестве проверки состояния
  • .{0,7}S означает 0-7 любых символов (кроме новой строки), за которыми следуют пробелы S . это делается для того, чтобы убедиться, что в следующих 8 символах есть хотя бы один совпадающий S
  • чтобы убедиться, что совпадения содержат хотя бы один видимый символ в позициях 11-18, вы можете изменить S на [^x00-x20] , который включает обратную сторону всех непечатаемых символов и ПРОБЕЛ ( x20 ), см. Таблицу наhttps://web.itu.edu.tr/sgunduz/courses/mikroisl/ascii.html

Ответ №2:

используйте class S; без пробела char.

 a=0123456789abcdeg123456efsgtext1234500th23sdfksbfk

$ echo $a| perl -pe 's/(?<=^.{10})S{8}/xxxxxxxxxxxxxxxxx/'

0123456789xxxxxxxxxxxxxxxxx3456efsgtext1234500th23sdfksbfk