У меня нет компьютера для тестирования, но это должно работать с gnused
:
sed 'H;1h;$!d;g;s/.*pattern1/@@@/;s/\n[^\n]*pattern2[^\n]*//;H;g;s/\(.*pattern1\).*@@@/\1/'
Вместо @@@
используйте любую последовательность символов, о которой известно, что она не является частью файла.
с помощью sed
можно сделать:
sed -E 's/(-[^-]*){2}$//' infile
соответствует шаблону типа -anything
дважды (...){2}
с конца $
каждой строки и удаляет его.
$ sed 's/-[[:alnum:]]*-[[:alnum:]]*$//' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Здесь используется sed
для сопоставления двух последних подстрок, разделенных тире -в каждой строке, и их удаления. [[:alnum:]]
будет соответствовать любому буквенно-цифровому символу.
Вы можете сократить его до
sed 's/\(-[[:alnum:]]*\)\{2\}$//' file
т. е. сопоставить и удалить два набора -[[:alnum:]]*
в конце каждой строки.
В GNU awk
вы также можете
$ awk -F '-' 'BEGIN { OFS=FS } { NF -= 2; print }' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
но такое изменение NF
не является переносимым, и его следует избегать (нет гарантии, что это изменит текущую запись ). Например, это не будет работать с BSD awk
.
В стандарте awk
, не прибегая к использованию sub()
(, которое будет просто имитировать sed
), вам придется воссоздать текущую запись из полей, которые вы хотели бы использовать (в нашем случае., все поля, кроме двух последних дефисов -, разделены):
$ awk -F '-' 'BEGIN { OFS=FS } { nf = split($0,a) - 2; $0=""; for (i=1; i<=nf; ++i) $i = a[i]; print }' file
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
С rev
иcut
:
rev file | cut -d'-' -f3- | rev
Перевернуть строки, cut
поле 3 до конца строки и снова перевернуть текст.
Сgrep
(и PCRE):
grep -Po '.*(?=(-[^-]*){2}$)' file
-P
использовать совместимые с perl -регулярные выражения с положительным опережением (?...)
, содержащие два совпадения -
, за которыми следуют любые не--
символы -o
печатать только совпадающие детали $ perl -F- -lane 'print join "-", @F[0..($#F-2)]' googleapis.txt
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy
Каждая входная строка автоматически разбивается на массив @F
с использованием разделителя -
.
Затем он печатает фрагмент массива всех полей, кроме двух последних, повторно -соединенных с -
символами.
вы можете сделать это разными способами, как показано здесь:
$ perl -F- -pale '$"="-";$#F-=2;$_="@F"' file
Разделить линии на тире, установить для соединения элементов массива значение тире, обрезать последние два элемента и установить текущую строку в массив, соединенный тире.
$ awk -F- '{
t = $1
for ( i=2; i<NF-1; i++ ) t = t FS $i
$0 = t
}1' file
Это при простой обработке строк:
$ perl -lne 'print substr($_, 0, rindex($_,"-",-1+rindex($_,"-")))' file
.
$ sed -ne '
y/-/\n/
:a;h;s/\n/-/;/\n.*\n/ba
g;P
' file
Результаты:
bucket,abc-def-ghi
bucket,dde-wwq-ooi
instance,jkl-mno-1-zzz
disk,pqr-stu-10-kuy