Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace first occurrence with sed?

Tags:

bash

sed

awk

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 ?

like image 208
user1365697 Avatar asked Feb 12 '19 12:02

user1365697


People also ask

Which is the correct command to replace the first occurrence?

By default, the sed command replaces the first occurrence of the pattern in each line and it won't replace the second, third… occurrence in the line.

How do you replace a line in a file with sed?

Find and replace text within a file using sed command Use Stream EDitor (sed) as follows: sed -i 's/old-text/new-text/g' input.txt. The s is the substitute command of sed for find and replace. It tells sed to find all occurrences of 'old-text' and replace with 'new-text' in a file named input.txt.

What is sed option?

sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline). While in some ways similar to an editor which permits scripted edits (such as ed ), sed works by making only one pass over the input(s), and is consequently more efficient.


3 Answers

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.

like image 69
ralz Avatar answered Oct 19 '22 22:10

ralz


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.

like image 29
RavinderSingh13 Avatar answered Oct 20 '22 00:10

RavinderSingh13


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.

like image 42
potong Avatar answered Oct 20 '22 00:10

potong