Вы не можете сделать это без особых затруднений.
Как указано в руководстве GNU sed :
г
Примените замену ко всем совпадениям к регулярному выражению , а не только к первому.
номер
Заменить только число -ное совпадение регулярное выражение .
взаимодействие в команде s
Примечание: стандарт POSIX не определяет, что должно происходить при смешивании модификаторов g
и число , и в настоящее время нет общепринятого значения в реализациях sed. Для GNU sed взаимодействие определяется следующим образом: игнорировать совпадения до числа -го, а затем сопоставлять и заменять все совпадения с числа -го и далее.)
В Mac OS X, однако, это работает:
▶ sed 's/foo/bar/3' <<< 'foofoofoofoofoo'
foofoobarfoofoo
Как это сделать:
▶ sed 's/foo/bar/g' <<< 'foofoofoofoofoo'
barbarbarbarbar
Но ошибка, указанная в вопросе, выдается, если они используются вместе.
@ oguzismail предоставил умное и простое решение, и я добавил это дополнительное объяснение, потому что я думал, что это будет полезно. 1 Более ранняя версия его ответа показала это, который, что смущает, ничего не сделал при тестировании:
▶ sed ':a; s/foo/bar/3; ta' <<< 'foofoofoofoofoo'
foofoofoofoofoo
Руководство BSD также не дает никаких объяснений. Тем не менее, руководство POSIX гласит:
Команды b, t и: документированы так, чтобы игнорировать начальные пробелы, но не упоминается о пробелах в конце.
Таким образом, это работает:
▶ sed -e :a -e s/foo/bar/3 -e ta <<< 'foofoofoofoofoo'
foofoobarbarbar
Это также работает:
▶ sed '
:a
s/foo/bar/3
ta
' <<< 'foofoofoofoofoo'
foofoobarbarbar
В любом случае сценарий заменяет 3-й foo
на bar
в цикле до тех пор, пока замена не завершится неудачей, после чего сценарий заканчивается. Обратите внимание на использование t
(test), который разветвляется, только если предыдущая команда s///
что-то заменила.
Чтобы понять, что скрипт делает в каждой из итераций своего цикла, полезно:
▶ sed -n -e :a -e s/foo/bar/3p -e ta <<< 'foofoofoofoofoo'
foofoobarfoofoo
foofoobarbarfoo
foofoobarbarbar
1 Первоначальная версия этого ответа не имела объяснения, хотя сейчас она значительно расширена. Огуз указал, что он предпочитает, чтобы я добавил эту информацию в отдельном ответе.