Я хочу удалить из файла две конкретные последовательные строки, соответствующие шаблонам из определенной строки.
Например, содержимое файла выглядит следующим образом.
Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5: xyz
Line6: Name: 456
Line7: abc
Я хочу найти строки, начиная со строки 4, соответствующие шаблону 1-й строки, начинающемуся с «Имя:», и соответствующие шаблону 2-й строки, начинающемуся с пробела, и удалить две последовательные строки.
Есть ли эффективный способ сделать это с помощью оболочки sed
или чего-то еще?
Чтобы внести немного ясности, я хочу удалить информацию о подписи/контрольной сумме из MANIFEST.MF.
Пример MANIFEST.MF, как показано ниже: Из файла манифеста ниже я хочу удалить запись «Имя:». Запись «Имя:» может быть в одну строку или в 2 (или более) строк.
Первоначально мое решение было таким: найти первую запись "Name: ", за которой следует запись "SHA-256-Digest: " и удалить ее до конца файла. К сожалению, это решение имеет проблему удаления одной нужной записи в середине. Например, "NetBeans-Simply-Convertible: " также удаляется.
Итак, теперь я хочу удалить запись "Name: ", если она доступна в 1 строке или запись, охватывающую 2 или более строк. Но я не должен терять записи типа "NetBeans-Simply-Convertible: " при удалении записей "Name: ".
Я уже удаляю записи "SHA-256-Digest:" с помощью следующей команды в файлеsed -i "/^\SHA-256-Digest: /d" $manifest_file
Manifest-Version: 1.0
Version-Info: ....
Name: com/abc/xyz/pqr/client/relationship/message/notifier/Relati
onshipUpdateNotifierFactory.class
SHA-256-Digest: cSSyk6Y2L2F9N6FPtswUkxjF2kelMkGe4bFprcQ+3uY=
Name: com/abc/xyz/pqr/client/relationship/ui/BaseRelationshipView
$5.class
SHA-256-Digest: w9HgRjDuP024U4CyxeKPYFe6rzuzxZF3b+9LVG36XP8=
Name: com/abc/xyz/pqr/client/impl/MofRelationshipAgentImpl.class
SHA-256-Digest: GwIBIU+UdPtjyRhayAVM90Eo+SwCT/kP65dI59adEnM=
Name: com/abc/xyz/pqr/client/settings/ConvertibleProperties.class
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
vertibleProperties
SHA-256-Digest: 5FszAtfpPXcLx/6FBWbfeg6E4fwFMRozV+Q+3rReATc= ...
Ожидаемый результат:
Manifest-Version: 1.0
Version-Info: ....
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}Con
vertibleProperties
...
решение1
awkподход:
Допустим, у нас есть следующий входной файл file.txt
(учитывая, что каждая строка содержит Line<number>:
в качестве первого поля):
Line1: a
Line2: b
Line3: c
Line4: Name: 123
Line5: xyz
Line6: Name: 456
Line7: abc
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11: abc
Line12: Name: 333
Line13: ccc
awk '{ if ($2 == "Name:") {
if ((getline l) > 0){
if (l ~ /^\S+ \S+/) { next } else { print $0 RS l }
}
} else { print }
}' file.txt
Выход:
Line1: a
Line2: b
Line3: c
Line8: Name: 111
Line9: www
Line10: Num: 222
Line11: abc
'getline var'- считывает следующую запись из ввода awk в переменнуюvar
Theполучитьлиниюкоманда возвращает 1, если находит запись, и 0, если обнаруживает конец файла.
решение2
Видите ли, то, о чем вы спрашиваете, неясно: один ответ удаляет 4 строки (две совпадающие и две последующие); другой удаляет всеносоответствующие строки...
Я добавлю то, что, как я понял, вы хотите: я удаляю 2 строки, одну совпадающую Name: 123
и одну последующую. Я делаю это с помощью sed
:
sed -e '/Name: 123/{N;d}' filename
решение3
С использованием ed
:
$ printf '%s\n' 'g/^ / s///\' '-,.j' 'g/^Name: /d' 'g/SHA-256-Digest: /d' '4,$g/^$/d' ,p Q | ed -s file
Manifest-Version: 1.0
Version-Info: ....
NetBeans-Simply-Convertible: {com/abc/xyz/pqr/client/settings}ConvertibleProperties
Это применит следующий скрипт редактирования к вашему входному файлу:
g/^ / s///\
-,.j
g/^Name: /d
g/SHA-256-Digest: /d
4,$g/^$/d
,p
Q
Он состоит из шести отдельных команд:
Две команды
s///
и-,. j
применяются к каждой строке, которая начинается с символа пробела. Пустое регулярное выражение вs
команде повторно использует выражение^
из предыдущейg
команды (которое используется для применения одной или нескольких команд к строкам, соответствующим регулярному выражению), поэтомуs
команда удаляет первый пустой пробел в строках, которые начинаются с пустых пробелов.j
Затем команда объединяет измененную строку с предыдущей строкой. Это фактически отменяет перенос строк во входных данных.Команда
d
применяется ко всем строкам, начинающимся сName:
, удаляя их.Аналогично
SHA-256-Digest:
удаляются строки, начинающиеся с .Пустые строки удаляются, начиная с 4-й.
Мы выводим весь буфер на стандартный вывод для отображения результата.
Q
безоговорочно выходит из редактора (можно использоватьwq
для записи изменений обратно в исходный файл).
решение4
sed -e '
4,$!d; # skip non-relevant portion
/Name:/N; # grab the line coming after Name:
/\n.* /d; # what we were after is not this
P;D
' yourfile