У меня есть несколько файлов с текстом, для которого нужна замена. Текст запускается и заканчивается тем же шаблоном каждый раз, но содержание, промежуточное шаблоны, является переменным. Шаблоны могут появиться посреди строк, и содержание между ними часто охватывает несколько строк.
Только будет отдельное проявление запуска и закончит шаблон в каждом файле.
Мне нужен метод командной строки для замены текста между шаблонами, включая сами шаблоны. Вывод в новый файл или редактирование на месте прекрасны.
Команда, которая воздействует на единственный файл, будет работать, поскольку я могу циклично выполниться через файлы и применить команду сам. Я делал попытку a sed
решению, но могло только удаться заменить все строки.
Пример текста был бы:
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: Security-Start Bs86gKI-734Lw#32_nP/5589Zfb8Wj-
sW93j9b Security-End, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Шаблон запуска Security-Start
и шаблон конца Security-End
. Я хочу заменить шаблоны и все промежуточное со словом REDACTED
.
Я хотел бы, чтобы вывод был:
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Обратите внимание на то, что текст между этими двумя шаблонами может быть таким длинным, что он охватывает несколько строк, это довольно случайно в длине. Это не ясно в примере выше
Любой язык, который доступен по умолчанию в системе Ubuntu, будет прекрасен. Мои первые мысли являются 'sed' или 'awk', но независимо от того, что Вы довольны, будет прекрасен.
Это должно работать для вас:
sed -e '/Security-Start/{ N; s/Security-Start.*Security-End/REDACTED/ }'
/Security-Start/
поиск «Security-Start» s/Security-Start.*Security-End/REDACTED/
в конечном результате. Для более чем двух строк используйте эту:
sed -n '1h; 1!H; ${ g; s/Security-Start.*Security-End/REDACTED/p }'
Прочитайте здесь
Если файлы не слишком велики, вы можете использовать perl в режиме slurp :
$ perl -0777 -pe 's/Security-Start.*Security-End/REDACTED/s' file
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Параметр командной строки -0777
эффективно удаляет разделитель записей, так что весь файл взломан. Модификатор s
regex заставляет perl включать символы новой строки в .
, что делает совпадение выражений между строками.
В качестве альтернативы, с циклом sed:
$ sed '/Security-Start/ {:a; $!N; s/Security-Start.*Security-End/REDACTED/; t; ba}' file
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
С помощью GNU sed вы можете заменить t; ba
(переход при успешной замене; (в противном случае) переход на :a
) на [ 117] (переход к :a
на и успешной замене).
Более ручным подходом было бы заменить все символы новой строки во входном файле на NULL, использовать простое perl
не жадное регулярное выражение, чтобы выполнить замену, а затем поместить символы новой строки обратно:
$ tr '\n' '\0' < file |
perl -pe 's/Security-Start.*?Security-End/Security: REDACTED/g' |
tr '\0' '\n'
Cable Type ID:135, Installation ID:62, Alpha Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Beta Conductor Origin:
Tolerance Report B74 - 3rd June 1996, Phase Conductor Size:
45mm, Security: Security: REDACTED, Location ID:889, Protective Earth Size:
67mm, Protective Earth Max Current (A): 4, Overload Time...
Вот как вы можете сделать это с помощью awk:
awk -v RS='Security-Start.*Security-End' -v ORS= '1;NR==1{printf "REDACTED"}' file