Мне нужно удалить все между вторым =
в строке и первым /
в строке, но оставить =
на месте. Я пробовал много, много вещей, самая последняя из которых -
sed -i 's/=[^/]*//
решение1
Основываясь только на текстовом описании, без примера ввода/вывода, я придумал следующее:
$ echo "foo=bar=baz/quux" | sed 's/\(.*=.*\)=.*\/\(.*\)/\1=\2/'
foo=bar=quux
Насколько это близко к тому, что вы хотите?
решение2
Начал писать об утверждениях look-ahead и look-behind, только чтобы узнать, что sed их не поддерживает! Это должно сработать:
sed -i 's!\(=[^=]*=\)[^/]*/!\1!'
- Поскольку мы используем
/
символ в регулярном выражении, мы меняем разделительs
команды на!
\(=[^=]*=\)
это группа захвата, которая соответствует одному=
символу, за которым следует ноль или более других символов, за которыми следует еще один=
символ. Эта часть нужна, чтобы убедиться, что=
перед удаляемой подстрокой есть два символа, как вы сказали, вам нужно[^/]*/
соответствует всему, что находится между разделителями и вторым разделителем\1
заменяет всю совпавшую строку на то, что соответствует группе захвата\(=[^=]*=\)
решение3
Вот одно из решенийperl
$ echo 'foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
foo=bar=quux
$ echo 'abc=foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
abc=foo=bar=baz/quux
Как видно из примеров выше, это ограничивает удаление текста только со 2-го =
по/
^([^=]+=){2}\K
от начала строки найти2
последовательность не-=
текста, за которым следует=
.\K
Означает положительный просмотр назад, не являющийся частью строки замены[^=/]+/
означает один или несколько не-=/
символов, заканчивающихся на/
- Если такой текст найден, он удаляется.
То же самое решение сsed
$ echo 'foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'
foo=bar=quux
$ echo 'abc=foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'
abc=foo=bar=baz/quux
Он не поддерживает конструкции просмотра вперед/назад, поэтому при замене используется группа захвата и обратная ссылка.