Сед делать замену на строку, но пропустить первое появление - PullRequest
11 голосов
/ 30 января 2010

Я прошел через седан один лайнер , но у меня все еще проблемы с моей целью.Я хочу заменить соответствующие строки на все, кроме первого вхождения строки.Мое точное использование было бы:

 $ echo 'cd /Users/joeuser/bump bonding/initial trials' | sed <<MAGIC HAPPENS>
 cd /Users/joeuser/bump\ bonding/initial\ trials

Строка заменила пробел в bump bonding на косую черту bump\ bonding, чтобы я мог выполнить эту строку (поскольку, когда пробелы не экранированы, я быя не смогу перейти на него)команда.Но это не ответило на мой вопрос.Мне все еще интересно ... как бы вы использовали sed, чтобы исправить это?

Ответы [ 3 ]

11 голосов
/ 30 января 2010

Вы можете избежать проблемы с g и n

Замените их все, затем отмените первый:

sed -e 's/ /\\ /g' -e 's/\\ / /1'

Вот еще один метод, использующий команду t branch-if-replace:

sed ':a;s/\([^ ]* .*[^\\]\) \(.*\)/\1\\ \2/;ta'

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

8 голосов
/ 30 января 2010
s/ /\\ /2g

2 указывает, что должен применяться второй, а g указывает, что все остальные также должны применяться. (Вероятно, это работает только в GNU sed. Согласно открытой базовой спецификации группы: « Если указаны оба значения g и n , результаты не определены. » ) * +1010 *

1 голос
/ 30 января 2010

используйте awk

$ echo cd 'blah blah/thing/another space/' | awk '{for(i=2;i<NF;i++) $i=$i"\\"}1'
cd blah\ blah/thing/another\ space/

$ echo 'cd /Users/joeuser/bump bonding/initial trials' | awk '{for(i=2;i<NF;i++) $i=$i"\\"}1'
cd /Users/joeuser/bump\ bonding/initial\ trials
...