sed: удалить все вхождения строки, кроме первого

14

У меня есть журнал с метками времени. Иногда в одной строке указывается несколько временных меток. Теперь я хотел бы удалить все метки времени из строки, но оставить первую.

Я могу сделать, s/pattern//2но это только удаляет второе вхождение и sedне позволяет что-то подобное s/pattern//2-.

Какие-либо предложения?

Фолькерт ван Хеусден
источник
Я должен был сказать, что это sed of busybox. Простите за это.
Фолькерт ван Хойсден

Ответы:

4

С GNU sed:

sed 's/pattern//2g'

В 2указывает , что второй шаблон и все остальные gдолжны удалить. Так что это будет первым.

αғsнιη
источник
1
Какой Cygwin имеет (порт, видимо), а MacOS нет. АЧХ! Это решение намного элегантнее.
r_alex_hall
7

Это должно сработать (замените _ чем-то другим, если это вступит в конфликт с вашими журналами):

sed -e 's/pattern/_&/1' -e 's/\([^_]\)pattern//g' -e 's/_\(pattern\)/\1/'
jlliagre
источник
1
если вам нужен уникальный разделитель, используйте \n.
mikeserv
5
sed -e ':begin;s/pattern//2;t begin'

или без седо гото:

sed -e 's/\(pattern\)/\1\n/;h;s/.*\n//;s/pattern//g;H;g;s/\n.*\n//'

Общие решения для удаления из n-й позиции (например, 3):

sed -e ':begin;s/pattern//4;t begin'
sed -e 's/\(pattern\)/\1\n/;h;s/.*\n//3;s/pattern//g;H;g;s/\n.*\n//'
jfg956
источник
1

Небольшое изменение в ответе @ jillagre (измененное для устойчивости) может выглядеть так:

sed 's/p\(attern\)/p\n\1/;s///g;s/\n//'

... но в некоторых случаях sedвам может потребоваться заменить nв правой части первого s///оператора \nubstitution буквальный символ смещения.

mikeserv
источник