Исходный файл
claudio
antonio
claudio
michele
Я хочу изменить только первое вхождение "Клаудио" с "Клаудия", чтобы файл результата
claudia
antonio
claudio
michele
я пытался
sed -e '1,/claudio/s/claudio/claudia/' nomi
Но выполнить глобальную замену. Почему?
info sed
: (0,/REGEXP/
: В спецификации адреса можно использовать номер строки, равный 0,0,/REGEXP/
так чтоsed
он также попытается сопоставить REGEXP в первой строке ввода. Другими словами,0,/REGEXP/
это аналогично1,/REGEXP/
, за исключением того, что если ADDR2 совпадает с самой первой строкой ввода, форма 0, / REGEXP / будет считать его завершающим диапазон, тогда как форма 1, / REGEXP / будет соответствовать началу диапазона и, следовательно, составит диапазон диапазона. до второго появления регулярного выражения)awk '/claudio/ && !ok { sub(/claudio/,"claudia"); ok=1 } 1' nomi
должен сделатьОтветы:
Если вы используете GNU
sed
, попробуйте:sed
не начинает проверять регулярное выражение, заканчивающее диапазон, до окончания строки, начинающей этот диапазон.Из
man sed
(POSIX manpage, выделение мое):С помощью
awk
Диапазон
awk
работы больше, чем вы ожидали:Объяснение:
NR==1,/claudio/
Это диапазон, который начинается со строки 1 и заканчивается первым появлением
claudio
.sub(/claudio/, "claudia")
Пока мы находимся в диапазоне, эта команда замещения выполняется.
1
Загадочные сокращения этого awk для печати строки.
источник
sed
хотя.awk '!r && /claudio/ {sub(/claudio/,"claudia"); r=1} 1'
awk !x{x=sub(/claudio/,"claudia")}1
0,/claudio/
Вот еще 2 программных действия с sed: они оба читают весь файл в одну строку, тогда поиск заменит только первую.
С комментарием:
источник
Новая версия GNU
sed
поддерживает эту-z
опцию.Вы можете использовать эту опцию, когда хотите
sed
работать над разными строками.возвращается
источник
Вы можете использовать
awk
с флагом, чтобы узнать, была ли замена уже сделана. Если нет, продолжайте:источник
На самом деле это очень просто, если вы просто настроите небольшую задержку - нет необходимости искать ненадежные расширения:
Это просто откладывает первую строку на вторую и вторую на третью и т. Д.
Это печатает:
источник
И еще один вариант
Преимущество в том, что он использует двойные кавычки, так что вы можете использовать переменные внутри, т.е.
источник
Это также можно сделать без пробела удержания и без объединения всех строк в пространство образца:
Объяснение: Мы пытаемся найти «claudio», и если мы делаем это, мы прыгаем в маленькую петлю print-load между
:x
иbx
. В противном случае мы печатаем и перезапускаем скрипт со следующей строкой.источник
источник
Sumary
Синтаксис GNU:
Или даже (использовать только один раз слово для замены:
Или в синтаксисе POSIX:
работает с любым sed, обрабатывает только столько строк, сколько необходимо, чтобы найти первую
claudio
, работает, даже еслиclaudio
находится в первой строке и короче, так как использует только одну строку регулярного выражения.подробность
Чтобы изменить только одну строку, вам нужно выбрать только одну строку.
Используя
1,/claudio/
(из вашего вопроса) выбирает:claudio
.Чтобы выбрать любую строку
claudio
, используйте:И чтобы выбрать только первое
claudio
в файле, используйте:Затем вы можете сделать замену только в этой строке:
Что изменит только первое вхождение совпадения с регулярным выражением в строке, даже если их может быть больше, чем в первой строке, соответствующей регулярному выражению.
Конечно,
/claudio/
регулярное выражение может быть упрощено до:И затем, единственное, чего не хватает, это напечатать все остальные строки без изменений:
источник