How to replace first occurrence with sed?

10,416

Solution 1

This should do what you want:

sed -i "0,/name:/{s/name:.*/name: ${NEW_VALUE}/}" ./myFile

It finds the first occurrence of name: and then does the substitution, which is replace 'name: followed by any characters' (.* means any sequence of characters) with 'name: ${NEW_VALUE}' where NEW_VALUE is your dynamical variable from your example.

From man sed

0,addr2

Start out in "matched first address" state, until addr2 is found. This is similar to 1,addr2, except that if addr2 matches the very first line of input the 0,addr2 form will be at the end of its range, whereas the 1,addr2 form will still be at the beginning of its range. This works only when addr2 is a regular expression.

Solution 2

If you are ok with awk then please try following.

awk '/name/ && ++count==1{sub(/name:.*/,"name: NEW VALUE!!!")} 1'  Input_file

In case you have a shell variable and you want to add its value to awk code then try following.

val="new_vaue"
awk -v value="$val" '/name/ && ++count==1{sub(/name:.*/,"name: "value)} 1'  Input_file

In case you want to save output into Input_file itself then append > temp_file && mv temp_file Input_file to above code.

Solution 3

This might work for you (GNU sed):

sed -i "/\(name:\).*/{s//\1 ${NEW_VALUE}/;:a;n;ba}" ./myFile

Match on name:, substitute new value and then read and print the remainder of the file.

Or alternative:

sed -z -i 's/\(name:\).*/\1 '"${NEW_VALUE}"'/M' file

N.B. the M flag to the substitution command to restrict the .* within a line.

Share:
10,416

Related videos on Youtube

user1365697
Author by

user1365697

Updated on June 04, 2022

Comments

  • user1365697
    user1365697 almost 2 years

    I have file with many name: I want to replace only the first one

    sed -i "s/\(name:\).*/\1 ${NEW_VALUE}/" ./myFile
    
    Input
    -  martin:
        name: Martin D'vloper
        job: Developer
        skills:
          - python
          - perl
          - pascal
    -  tabitha:
        name: Tabitha Bitumen
        job: Developer
        skills:
          - lisp
          - fortran
          - erlang
    

    output to change only the first name Martin D'vloper

    -  martin:
            name: NEW VALUE!!!
            job: Developer
            skills:
              - python
              - perl
              - pascal
        -  tabitha:
            name: Tabitha Bitumen
            job: Developer
            skills:
              - lisp
              - fortran
              - erlang
    

    It changed all names

    I saw something with different syntax

    sed '0,/pattern/s/pattern/replacement/' filename
    

    but I can't change sed to this because the dynamic value Could you advise me how to replace only the first one with my syntax ?

  • RavinderSingh13
    RavinderSingh13 about 5 years
    @user1365697, see my 2nd solution where you could substitute values by variable(from shell to awk) and let me know if this helps.
  • Levi Uzodike
    Levi Uzodike about 3 years
    I have GNU sed version 4.2.1, and it doesn't have the -z option.
  • Levi Uzodike
    Levi Uzodike about 3 years
    Explanation of 1st option: when the pattern "name:" followed by any number of characters in the line are found, save "name:" as the first sub-expression(/\(name:\).*/), then do these commands({): substitute(s) whatever was matched(//) for the 1st sub-expression(\1) followed by a space and what's saved in the variable NEW_VALUE(*space*${NEW_VALUE}/) then(;) create label 'a' right here in this command(:a) then(;) print and go to the next line or exit if there aren't any more(n) then(;) branch back to label a(ba). End of commands for matched pattern(}).