sed: видалити всі виникнення рядка, крім першого


14

У мене є журнал файлів із часовими позначками. Інколи в одному рядку є кілька часових позначок. Тепер я хотів би зняти всі часові позначки з рядка, але зберегти першу.

Я можу зробити, s/pattern//2але це видаляє лише друге явище і sedне дозволяє щось подібне s/pattern//2-.

Будь-які пропозиції?


Я повинен був сказати, що це сед зайнятого ящика. Вибачте за це.
Фолкерт ван Хейсден

Відповіді:


4

З GNU sed:

sed 's/pattern//2g'

В 2вказує , що другий шаблон і всі інші gповинні видалити. Так це збереже перше.


1
Який у Cygwin (порт, мабуть), а MacOS - ні. А-а-а! Це рішення настільки елегантніше.
r_alex_hall

7

Це має спрацювати (замініть _ чимось іншим, якщо воно зіткнеться з вашими журналами):

sed -e 's/pattern/_&/1' -e 's/\([^_]\)pattern//g' -e 's/_\(pattern\)/\1/'

1
якщо ви коли-небудь хочете унікальний роздільник, використовуйте \n.
mikeserv

5
sed -e ':begin;s/pattern//2;t begin'

або без sed goto:

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//'

1

Незначна зміна відповіді @ jillagre (модифікована для надійності) може виглядати так:

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

... але в деяких випадках sedвам може знадобитися замінити nправу частину першого s///заяви про встановлення буквальним \nсимволом ewline.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.