Find a string and replace another string after the first is found
Clash Royale CLAN TAG#URR8PPP
up vote
1
down vote
favorite
File:
1
2
3
4
1
5
6
7
4
I would like to search for a string, in this case 1
, and then change the next string of 4
to 8
.
Expected output:
1
2
3
8
1
5
6
7
4
I've tried:
cat file | sed '/1/ s/4/8/'
But that only looks for a string to change in that line.
I also can't use line number to replace in my original file because there might be a different number of lines between the first string and the second.
I do not have GNU sed installed.
sed
add a comment |Â
up vote
1
down vote
favorite
File:
1
2
3
4
1
5
6
7
4
I would like to search for a string, in this case 1
, and then change the next string of 4
to 8
.
Expected output:
1
2
3
8
1
5
6
7
4
I've tried:
cat file | sed '/1/ s/4/8/'
But that only looks for a string to change in that line.
I also can't use line number to replace in my original file because there might be a different number of lines between the first string and the second.
I do not have GNU sed installed.
sed
2
if the first occurence of 4 has to be changed you don't need anythingsed "/4/8/" file
that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
â francois P
Jan 22 at 21:29
2
What if there's another1
further down which is followed by another4
? Do you need to replace only the 1st4
in the file which occurs after a1
or do you need to repeat that for each 1st4
that follows after a1
?
â don_crissti
Jan 22 at 21:36
Yes I edited the file and expected output. Sorry
â user1712037
Jan 22 at 21:46
@user1712037,how aboutawk
solution?
â RomanPerekhrest
Jan 22 at 21:49
Sure. What would the awk syntax look like?
â user1712037
Jan 22 at 21:51
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
File:
1
2
3
4
1
5
6
7
4
I would like to search for a string, in this case 1
, and then change the next string of 4
to 8
.
Expected output:
1
2
3
8
1
5
6
7
4
I've tried:
cat file | sed '/1/ s/4/8/'
But that only looks for a string to change in that line.
I also can't use line number to replace in my original file because there might be a different number of lines between the first string and the second.
I do not have GNU sed installed.
sed
File:
1
2
3
4
1
5
6
7
4
I would like to search for a string, in this case 1
, and then change the next string of 4
to 8
.
Expected output:
1
2
3
8
1
5
6
7
4
I've tried:
cat file | sed '/1/ s/4/8/'
But that only looks for a string to change in that line.
I also can't use line number to replace in my original file because there might be a different number of lines between the first string and the second.
I do not have GNU sed installed.
sed
edited Jan 22 at 21:46
asked Jan 22 at 21:20
user1712037
53117
53117
2
if the first occurence of 4 has to be changed you don't need anythingsed "/4/8/" file
that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
â francois P
Jan 22 at 21:29
2
What if there's another1
further down which is followed by another4
? Do you need to replace only the 1st4
in the file which occurs after a1
or do you need to repeat that for each 1st4
that follows after a1
?
â don_crissti
Jan 22 at 21:36
Yes I edited the file and expected output. Sorry
â user1712037
Jan 22 at 21:46
@user1712037,how aboutawk
solution?
â RomanPerekhrest
Jan 22 at 21:49
Sure. What would the awk syntax look like?
â user1712037
Jan 22 at 21:51
add a comment |Â
2
if the first occurence of 4 has to be changed you don't need anythingsed "/4/8/" file
that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
â francois P
Jan 22 at 21:29
2
What if there's another1
further down which is followed by another4
? Do you need to replace only the 1st4
in the file which occurs after a1
or do you need to repeat that for each 1st4
that follows after a1
?
â don_crissti
Jan 22 at 21:36
Yes I edited the file and expected output. Sorry
â user1712037
Jan 22 at 21:46
@user1712037,how aboutawk
solution?
â RomanPerekhrest
Jan 22 at 21:49
Sure. What would the awk syntax look like?
â user1712037
Jan 22 at 21:51
2
2
if the first occurence of 4 has to be changed you don't need anything
sed "/4/8/" file
that's all /foo/ s/bar/foo/ means on line with foo .... substitute....â francois P
Jan 22 at 21:29
if the first occurence of 4 has to be changed you don't need anything
sed "/4/8/" file
that's all /foo/ s/bar/foo/ means on line with foo .... substitute....â francois P
Jan 22 at 21:29
2
2
What if there's another
1
further down which is followed by another 4
? Do you need to replace only the 1st 4
in the file which occurs after a 1
or do you need to repeat that for each 1st 4
that follows after a 1
?â don_crissti
Jan 22 at 21:36
What if there's another
1
further down which is followed by another 4
? Do you need to replace only the 1st 4
in the file which occurs after a 1
or do you need to repeat that for each 1st 4
that follows after a 1
?â don_crissti
Jan 22 at 21:36
Yes I edited the file and expected output. Sorry
â user1712037
Jan 22 at 21:46
Yes I edited the file and expected output. Sorry
â user1712037
Jan 22 at 21:46
@user1712037,how about
awk
solution?â RomanPerekhrest
Jan 22 at 21:49
@user1712037,how about
awk
solution?â RomanPerekhrest
Jan 22 at 21:49
Sure. What would the awk syntax look like?
â user1712037
Jan 22 at 21:51
Sure. What would the awk syntax look like?
â user1712037
Jan 22 at 21:51
add a comment |Â
5 Answers
5
active
oldest
votes
up vote
2
down vote
accepted
The POSIX-specified file editor, ex
, is capable of doing exactly that.
printf '%sn' '/1//4/s//8/' x | ex file.txt
ex
is capable of combining multiple addresses. So /1/
means "Go to" (or refer to) "the next line matching regex 1
." Then /4/
goes from that line to the next line matching 4
. And s//8/
has the usual meaning; as in Sed, a blank regex passed to the s
command means "reuse last regex used" which in this case is 4
.
To print the modified file but not save the changes, use the following command instead:
printf '%sn' '/1//4/s//8/' %p | ex file.txt
Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry
before the first line containing banana
after line 27:
printf '%sn' '27/banana/?cherry?d' x | ex file.txt
x
means to save changes and exit, and %p
means "print whole file." (%
is a synonym for 1,$
, which is an address range from the first line to the last line.)
add a comment |Â
up vote
1
down vote
To replace only the 1st PATTERN
that occurs after a MARKER
you could do:
sed '/MARKER/,$
/PATTERN/
x
//
x
b
g
s/PATTERN/REPLACEMENT/
' infile
Use a range (from the 1st MARKER
to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN
you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.
add a comment |Â
up vote
1
down vote
generic solution using awk
, consider the following modified input file with multiple 1
s and 4
s
$ cat ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
4
1
rrrrrr
4
1
4
Use a flag to indicate that 1
was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again
$ # first block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
1
foo
1
xyz
8
4
1
1
eeeee
4
1
rrrrrr
4
1
4
$ # second block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
8
1
rrrrrr
4
1
4
can be simplified for changing only first block
awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt
add a comment |Â
up vote
0
down vote
Awk
solution:
awk '$1==1 f++ f==1 && $1==4 $1=8 1' file
The output:
1
2
3
8
1
5
6
7
4
awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
â user1712037
Jan 22 at 22:28
@user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
â RomanPerekhrest
Jan 22 at 22:31
1
This won't work if there are multiple lines matching1
before the 1st4
that follows...
â don_crissti
Jan 22 at 23:07
@don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
â RomanPerekhrest
Jan 23 at 8:25
add a comment |Â
up vote
0
down vote
With awk it is more easy and compatible to any Nth occurrence needed
awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME
example :
-bash-4.4$ cat toto
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
-bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
1
2
3
4
5
6
1
2
3
---8
5
6
1
2
3
4
-bash-4.4$
only the second 4 is changed but not the first or the last.
1
but this is not even checking if1
occurred first...
â Sundeep
Jan 23 at 4:10
add a comment |Â
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
The POSIX-specified file editor, ex
, is capable of doing exactly that.
printf '%sn' '/1//4/s//8/' x | ex file.txt
ex
is capable of combining multiple addresses. So /1/
means "Go to" (or refer to) "the next line matching regex 1
." Then /4/
goes from that line to the next line matching 4
. And s//8/
has the usual meaning; as in Sed, a blank regex passed to the s
command means "reuse last regex used" which in this case is 4
.
To print the modified file but not save the changes, use the following command instead:
printf '%sn' '/1//4/s//8/' %p | ex file.txt
Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry
before the first line containing banana
after line 27:
printf '%sn' '27/banana/?cherry?d' x | ex file.txt
x
means to save changes and exit, and %p
means "print whole file." (%
is a synonym for 1,$
, which is an address range from the first line to the last line.)
add a comment |Â
up vote
2
down vote
accepted
The POSIX-specified file editor, ex
, is capable of doing exactly that.
printf '%sn' '/1//4/s//8/' x | ex file.txt
ex
is capable of combining multiple addresses. So /1/
means "Go to" (or refer to) "the next line matching regex 1
." Then /4/
goes from that line to the next line matching 4
. And s//8/
has the usual meaning; as in Sed, a blank regex passed to the s
command means "reuse last regex used" which in this case is 4
.
To print the modified file but not save the changes, use the following command instead:
printf '%sn' '/1//4/s//8/' %p | ex file.txt
Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry
before the first line containing banana
after line 27:
printf '%sn' '27/banana/?cherry?d' x | ex file.txt
x
means to save changes and exit, and %p
means "print whole file." (%
is a synonym for 1,$
, which is an address range from the first line to the last line.)
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
The POSIX-specified file editor, ex
, is capable of doing exactly that.
printf '%sn' '/1//4/s//8/' x | ex file.txt
ex
is capable of combining multiple addresses. So /1/
means "Go to" (or refer to) "the next line matching regex 1
." Then /4/
goes from that line to the next line matching 4
. And s//8/
has the usual meaning; as in Sed, a blank regex passed to the s
command means "reuse last regex used" which in this case is 4
.
To print the modified file but not save the changes, use the following command instead:
printf '%sn' '/1//4/s//8/' %p | ex file.txt
Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry
before the first line containing banana
after line 27:
printf '%sn' '27/banana/?cherry?d' x | ex file.txt
x
means to save changes and exit, and %p
means "print whole file." (%
is a synonym for 1,$
, which is an address range from the first line to the last line.)
The POSIX-specified file editor, ex
, is capable of doing exactly that.
printf '%sn' '/1//4/s//8/' x | ex file.txt
ex
is capable of combining multiple addresses. So /1/
means "Go to" (or refer to) "the next line matching regex 1
." Then /4/
goes from that line to the next line matching 4
. And s//8/
has the usual meaning; as in Sed, a blank regex passed to the s
command means "reuse last regex used" which in this case is 4
.
To print the modified file but not save the changes, use the following command instead:
printf '%sn' '/1//4/s//8/' %p | ex file.txt
Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry
before the first line containing banana
after line 27:
printf '%sn' '27/banana/?cherry?d' x | ex file.txt
x
means to save changes and exit, and %p
means "print whole file." (%
is a synonym for 1,$
, which is an address range from the first line to the last line.)
answered Jan 22 at 22:42
Wildcard
22k855154
22k855154
add a comment |Â
add a comment |Â
up vote
1
down vote
To replace only the 1st PATTERN
that occurs after a MARKER
you could do:
sed '/MARKER/,$
/PATTERN/
x
//
x
b
g
s/PATTERN/REPLACEMENT/
' infile
Use a range (from the 1st MARKER
to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN
you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.
add a comment |Â
up vote
1
down vote
To replace only the 1st PATTERN
that occurs after a MARKER
you could do:
sed '/MARKER/,$
/PATTERN/
x
//
x
b
g
s/PATTERN/REPLACEMENT/
' infile
Use a range (from the 1st MARKER
to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN
you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
To replace only the 1st PATTERN
that occurs after a MARKER
you could do:
sed '/MARKER/,$
/PATTERN/
x
//
x
b
g
s/PATTERN/REPLACEMENT/
' infile
Use a range (from the 1st MARKER
to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN
you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.
To replace only the 1st PATTERN
that occurs after a MARKER
you could do:
sed '/MARKER/,$
/PATTERN/
x
//
x
b
g
s/PATTERN/REPLACEMENT/
' infile
Use a range (from the 1st MARKER
to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN
you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.
edited Jan 22 at 22:56
answered Jan 22 at 22:40
don_crissti
46.6k15124153
46.6k15124153
add a comment |Â
add a comment |Â
up vote
1
down vote
generic solution using awk
, consider the following modified input file with multiple 1
s and 4
s
$ cat ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
4
1
rrrrrr
4
1
4
Use a flag to indicate that 1
was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again
$ # first block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
1
foo
1
xyz
8
4
1
1
eeeee
4
1
rrrrrr
4
1
4
$ # second block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
8
1
rrrrrr
4
1
4
can be simplified for changing only first block
awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt
add a comment |Â
up vote
1
down vote
generic solution using awk
, consider the following modified input file with multiple 1
s and 4
s
$ cat ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
4
1
rrrrrr
4
1
4
Use a flag to indicate that 1
was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again
$ # first block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
1
foo
1
xyz
8
4
1
1
eeeee
4
1
rrrrrr
4
1
4
$ # second block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
8
1
rrrrrr
4
1
4
can be simplified for changing only first block
awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt
add a comment |Â
up vote
1
down vote
up vote
1
down vote
generic solution using awk
, consider the following modified input file with multiple 1
s and 4
s
$ cat ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
4
1
rrrrrr
4
1
4
Use a flag to indicate that 1
was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again
$ # first block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
1
foo
1
xyz
8
4
1
1
eeeee
4
1
rrrrrr
4
1
4
$ # second block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
8
1
rrrrrr
4
1
4
can be simplified for changing only first block
awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt
generic solution using awk
, consider the following modified input file with multiple 1
s and 4
s
$ cat ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
4
1
rrrrrr
4
1
4
Use a flag to indicate that 1
was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again
$ # first block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
1
foo
1
xyz
8
4
1
1
eeeee
4
1
rrrrrr
4
1
4
$ # second block
$ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
1
foo
1
xyz
4
4
1
1
eeeee
8
1
rrrrrr
4
1
4
can be simplified for changing only first block
awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt
answered Jan 23 at 4:18
Sundeep
6,9511826
6,9511826
add a comment |Â
add a comment |Â
up vote
0
down vote
Awk
solution:
awk '$1==1 f++ f==1 && $1==4 $1=8 1' file
The output:
1
2
3
8
1
5
6
7
4
awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
â user1712037
Jan 22 at 22:28
@user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
â RomanPerekhrest
Jan 22 at 22:31
1
This won't work if there are multiple lines matching1
before the 1st4
that follows...
â don_crissti
Jan 22 at 23:07
@don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
â RomanPerekhrest
Jan 23 at 8:25
add a comment |Â
up vote
0
down vote
Awk
solution:
awk '$1==1 f++ f==1 && $1==4 $1=8 1' file
The output:
1
2
3
8
1
5
6
7
4
awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
â user1712037
Jan 22 at 22:28
@user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
â RomanPerekhrest
Jan 22 at 22:31
1
This won't work if there are multiple lines matching1
before the 1st4
that follows...
â don_crissti
Jan 22 at 23:07
@don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
â RomanPerekhrest
Jan 23 at 8:25
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Awk
solution:
awk '$1==1 f++ f==1 && $1==4 $1=8 1' file
The output:
1
2
3
8
1
5
6
7
4
Awk
solution:
awk '$1==1 f++ f==1 && $1==4 $1=8 1' file
The output:
1
2
3
8
1
5
6
7
4
answered Jan 22 at 21:58
RomanPerekhrest
22.4k12144
22.4k12144
awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
â user1712037
Jan 22 at 22:28
@user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
â RomanPerekhrest
Jan 22 at 22:31
1
This won't work if there are multiple lines matching1
before the 1st4
that follows...
â don_crissti
Jan 22 at 23:07
@don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
â RomanPerekhrest
Jan 23 at 8:25
add a comment |Â
awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
â user1712037
Jan 22 at 22:28
@user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
â RomanPerekhrest
Jan 22 at 22:31
1
This won't work if there are multiple lines matching1
before the 1st4
that follows...
â don_crissti
Jan 22 at 23:07
@don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
â RomanPerekhrest
Jan 23 at 8:25
awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
â user1712037
Jan 22 at 22:28
awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
â user1712037
Jan 22 at 22:28
@user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
â RomanPerekhrest
Jan 22 at 22:31
@user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
â RomanPerekhrest
Jan 22 at 22:31
1
1
This won't work if there are multiple lines matching
1
before the 1st 4
that follows...â don_crissti
Jan 22 at 23:07
This won't work if there are multiple lines matching
1
before the 1st 4
that follows...â don_crissti
Jan 22 at 23:07
@don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
â RomanPerekhrest
Jan 23 at 8:25
@don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
â RomanPerekhrest
Jan 23 at 8:25
add a comment |Â
up vote
0
down vote
With awk it is more easy and compatible to any Nth occurrence needed
awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME
example :
-bash-4.4$ cat toto
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
-bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
1
2
3
4
5
6
1
2
3
---8
5
6
1
2
3
4
-bash-4.4$
only the second 4 is changed but not the first or the last.
1
but this is not even checking if1
occurred first...
â Sundeep
Jan 23 at 4:10
add a comment |Â
up vote
0
down vote
With awk it is more easy and compatible to any Nth occurrence needed
awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME
example :
-bash-4.4$ cat toto
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
-bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
1
2
3
4
5
6
1
2
3
---8
5
6
1
2
3
4
-bash-4.4$
only the second 4 is changed but not the first or the last.
1
but this is not even checking if1
occurred first...
â Sundeep
Jan 23 at 4:10
add a comment |Â
up vote
0
down vote
up vote
0
down vote
With awk it is more easy and compatible to any Nth occurrence needed
awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME
example :
-bash-4.4$ cat toto
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
-bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
1
2
3
4
5
6
1
2
3
---8
5
6
1
2
3
4
-bash-4.4$
only the second 4 is changed but not the first or the last.
With awk it is more easy and compatible to any Nth occurrence needed
awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME
example :
-bash-4.4$ cat toto
1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
-bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
1
2
3
4
5
6
1
2
3
---8
5
6
1
2
3
4
-bash-4.4$
only the second 4 is changed but not the first or the last.
edited Jan 22 at 22:16
ilkkachu
49.8k674137
49.8k674137
answered Jan 22 at 22:07
francois P
914114
914114
1
but this is not even checking if1
occurred first...
â Sundeep
Jan 23 at 4:10
add a comment |Â
1
but this is not even checking if1
occurred first...
â Sundeep
Jan 23 at 4:10
1
1
but this is not even checking if
1
occurred first...â Sundeep
Jan 23 at 4:10
but this is not even checking if
1
occurred first...â Sundeep
Jan 23 at 4:10
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f418946%2ffind-a-string-and-replace-another-string-after-the-first-is-found%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
2
if the first occurence of 4 has to be changed you don't need anything
sed "/4/8/" file
that's all /foo/ s/bar/foo/ means on line with foo .... substitute....â francois P
Jan 22 at 21:29
2
What if there's another
1
further down which is followed by another4
? Do you need to replace only the 1st4
in the file which occurs after a1
or do you need to repeat that for each 1st4
that follows after a1
?â don_crissti
Jan 22 at 21:36
Yes I edited the file and expected output. Sorry
â user1712037
Jan 22 at 21:46
@user1712037,how about
awk
solution?â RomanPerekhrest
Jan 22 at 21:49
Sure. What would the awk syntax look like?
â user1712037
Jan 22 at 21:51