Хотите заменить только первое вхождение с sed

Исходный файл

claudio antonio claudio michele 

Я хочу изменить только первое появление «claudio» с «claudia», поэтому результат файла

 claudia antonio claudio michele 

я пытался

 sed -e '1,/claudio/s/claudio/claudia/' nomi 

Но выполняйте глобальную замену. Почему?

7 Solutions collect form web for “Хотите заменить только первое вхождение с sed”

Если вы используете GNU sed , попробуйте:

 sed -e '0,/claudio/ s/claudio/claudia/' nomi 

sed не запускает проверку для регулярного выражения, которое заканчивает диапазон, до тех пор, пока строка, начинающая этот диапазон.

От man sed (POSIX manpage, акцент мой):

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

Использование awk

Диапазоны в awk работают больше, как вы ожидали:

 $ awk 'NR==1,/claudio/{sub(/claudio/, "claudia")} 1' nomi claudia antonio claudio michele 

Объяснение:

  • NR==1,/claudio/

    Это диапазон, который начинается с строки 1 и заканчивается первым вступлением claudio .

  • sub(/claudio/, "claudia")

    Пока мы находимся в диапазоне, эта команда подстановки выполняется.

  • 1

    Это критическая стенограмма awk для печати строки.

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

 sed -n ':a;N;$bb;ba;:b;s/\(claudi\)o/\1a/;p' file sed -n '1h;1!H;${g;s/\(claudi\)o/\1a/;p;}' file 

С комментарием:

 sed -n ' # don't implicitly print input :a # label "a" N # append next line to pattern space $bb # at the last line, goto "b" ba # goto "a" :b # label "b" s/\(claudi\)o/\1a/ # replace p # and print ' file 
 sed -n ' # don't implicitly print input 1h # put line 1 in the hold space 1!H # for subsequent lines, append to hold space ${ # on the last line g # put the hold space in pattern space s/\(claudi\)o/\1a/ # replace p # print } ' file 

Вы можете использовать awk с флагом, чтобы узнать, была ли замена уже выполнена. Если нет, продолжайте:

 $ awk '!f && /claudio/ {$0="claudia"; f=1}1' file claudia antonio claudio michele 

На самом деле это очень просто, если вы просто установите небольшую задержку – нет необходимости идти на недостоверные расширения:

 sed '$H;x;1,/claudio/s/claudio/claudia/;1d' <<\IN claudio antonio claudio michele IN 

Это просто переводит первую строку на вторую, а вторую на третью и т. Д.

Он печатает:

 claudia antonio claudio michele 

И еще один вариант

 sed --in-place=*.bak -e "1 h;1! H;\$! d;$ {g;s/claudio/claudia/;}" -- nomi 

Преимущество заключается в использовании двойной кавычки, поэтому вы можете использовать переменные внутри, т. Е.

 export chngFrom=claudio export chngTo=claudia sed --in-place=*.bak -e "1 h;1! H;\$! d;$ {g;s/${chngFrom}/${chngTo}/;}" -- nomi 

Это также можно сделать без пространства удержания и без учета всех строк в пространстве шаблонов:

 sed -n '/claudio/{s/o/a/;bx};p;b;:x;p;n;bx' nomi 

Объяснение: Мы пытаемся найти «claudio», и если мы это сделаем, мы перейдем к небольшому циклу печати-нагрузки между :x и bx . В противном случае мы печатаем и перезапускаем скрипт со следующей строкой.

 sed -n ' # do not print lines by default /claudio/ { # on lines that match "claudio" do ... s/o/a/ # replace "o" with "a" bx # goto label x } # end of do block p # print the pattern space b # go to the end of the script, continue with next line :x # the label x for goto commands p # print the pattern space n # load the next line in the pattern space (clearing old contents) bx # goto the label x ' nomi 
 sed -n '/claudia/{p;Q}' sed -n ' # don't print input /claudia/ # regex search { # when match is found do p; # print line Q # quit sed, don't print last buffered line { # end do block 
  • Вопрос: что означает «s / quiet init =. * $ //»?
  • Как заменить строку знаком доллара в sed?
  • Sed: расширение строки чисел до определенного количества цифр путем заполнения нулями
  • удалить строки файла из файла
  • Матч косой черты в ббе
  • Используя sed, чтобы избавиться от символов <>,
  • Две команды sed в одной команде
  • Замена шаблона переменной
  • Сед и две последовательные линии
  • Что делает :: делает в скрипте sed
  • Поиск и замена предложения с помощью пробелов с помощью команды sed
  • Как я могу заставить команду sed выполнять постоянные изменения в файле?
  • Linux и Unix - лучшая ОС в мире.