Как удалить строки до и после соответствия шаблону
У меня есть файл, как показано ниже. Я хочу найти шаблон ABC_DATA как переменную, и после совпадения я хочу удалить из первой предыдущей строки "multipath" строку, содержащую символ "}". "}" может быть после или в одной строке с ABC_DATA.
ОБРАЗЕЦ ВЫХОД
multipaths {
multipath {
wwid 360000970000267600432533030353944
alias ABC_DATA_11
}
multipath {
wwid 360000970000267600432533030353945
alias DEF_DATA_11
}
multipath {
wwid 360000970000267600432533030353946
alias ABC_DATA_12 }
multipath {
wwid 360000970000267600432533030353943
alias DEF_DATA_10
}
}
ОЖИДАЕМЫЙ ВЫХОД
multipaths {
multipath {
wwid 360000970000267600432533030353945
alias DEF_DATA_11
}
multipath {
wwid 360000970000267600432533030353943
alias DEF_DATA_10
}
}
4 ответа
$ awk -v RS='multipath\\s*{[^}]*ABC_DATA[^}]*}\\s*(\n|$)' -v ORS= '1' file
multipaths {
multipath {
wwid 360000970000267600432533030353945
alias DEF_DATA_11
}
multipath {
wwid 360000970000267600432533030353943
alias DEF_DATA_10
}
}
Использование sed, не совсем читаемое, но определенно возможное:
sed '
/^multipath {/ {
:l
/alias ABC_DATA/ {
:f
/}/ d
N
b f
}
/}/ b
N
b l
}' input
или одной строкой:
sed '/^multipath {/{:l; /alias ABC_DATA/{:f /}/d;N;bf};/}/b;N;bl};' input
Учитывая ваш пример, вы можете использовать это
perl
:
$ perl -0777 -lpe 's/\bmultipath\h+\{[^{}]*ABC_DATA[^{}]*}\s*//g' file
multipaths {
multipath {
wwid 360000970000267600432533030353945
alias DEF_DATA_11
}
multipath {
wwid 360000970000267600432533030353943
alias DEF_DATA_10
}
}
ed(1) тоже работает, если у вас есть строки глобального поиска, отличные от строк начала и конца области, которую вы хотите удалить:
echo $'g/ABC_DATA/?multipath?,/[\s\S]*}/s/.*//g\n ,n\n w\n q' | ed -s file
#or
echo $'g/ABC_DATA/?multipath?,/[\s\S]*}/d\n ,n\n w\n q' | ed -s file
-
echo
команда предоставляет команды ed,\n
это просто новые строки - того же можно добиться с помощью файлов heredocs или ed script, но это не работает для oneliners
что там на самом деле происходит:
- поиск ABC_DATA
- оттуда получите стартовую строку, выполнив поиск
multipath
вверх - получите конечную строку, выполнив поиск любого символа вниз (
[\s\S]*
) и заканчивая - и либо «отправить» его через
s
или удалить черезd
-
,n
предназначен только для печати всего вывода в оболочку и может быть опущен -
w
сохраняет иq
выходы - используйтеQ
вместо того и другого, если вы все еще экспериментируете и не хотите немедленно сохранять изменения обратно в файл.
однако для этого примера это не удастся из-за строки, содержащейalias ABC_DATA_12 }
Как обаABC_DATA
и}
находятся на одном уровне - я все еще вижу преимущества использования ed(1) и поэтому хотел поделиться этим подходом.