How to replace the last pattern using sed?


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting How to replace the last pattern using sed?
# 8  
Old 03-29-2011
No sed, but Ruby(1.9+)

Code:
$ ruby -0777  -ne 'i=$_.rindex("AAA")-1; puts $_[0..i-1] + "\nEEEEE" + $_[i+"AAA".size+1..-1]' file
AAAaaa
BBBbbb
CCCccc
EEEEEeee
DDDddd

# 9  
Old 03-30-2011
Code:
printf "G?AAA\n:s/AAA/EEEEE/g\n:wq\n" | vi -s infile >/dev/null

# 10  
Old 03-31-2011
Quote:
Originally Posted by ctsgnb
Code:
printf "G?AAA\n:s/AAA/EEEEE/g\n:wq\n" | vi -s infile >/dev/null

Hi, ctsgnb:

Regarding that usage of vi, you can't count on that working. Some (most?) vi clones will not read from stdin when it's not a terminal. The standard explicitly mentions this case and leaves it as undefined behavior. Also, it does not include a -s option for vi.

Even if it did, the sequence of commands is faulty. G makes the last line the current line and ?AAA then searches backward for "AAA". What if there's an "AAA" on that last line in the file and another "AAA" on a previous line? The search will not see that the current line is a match and will instead stop at the previous, earlier line, which is not what's desired. The backwards search needs to begin from line 1.

(The following is nothing but a stylistic note of personal preference. It's not really important but perhaps you may like it.)

Since printf reuses the format string until it has exhausted all of its arguments, you can rewrite it so that printf newline-terminates each string argument for you. It's easier to read when the embedded \n sequences are replaced with whitespace-delimited arguments. Additionally, should the ed/ex commands use %, \n, \t, etc..., there's no need to escape them (as there would be in the format string).

Code:
# Works fine but harder to read and vulnerable to metacharacters
printf "G?AAA\n:s/AAA/EEEEE/g\n:wq\n"

# Easier to read and no worries regarding format string metacharacters
printf '%s\n' 'G?AAA' :s/AAA/EEEEE/g :wq

Regards,
Alister
This User Gave Thanks to alister For This Post:
# 11  
Old 03-31-2011
with gnu awk:
Code:
gawk '{P=P $0 "\n"} END{printf gensub("(.*)AAA","\\1EEEE","",P)}' file

This works for last occurance on last line too eg (red text replaced):
Code:
AAAaaa
BBBbbb
CCCccc
AAAbbbbAAAAAAcccc
DDDddd

If your not worried about this case, no need for gnu awk:
Code:
awk '/AAA/{printf P;P=""}{P=P $0 "\n"} END{sub("AAA","EEEE",P); printf P}' file


Last edited by Chubler_XL; 03-31-2011 at 10:09 PM..
# 12  
Old 04-01-2011
@alister

First of all, thanks a lot for your comments, i really appreciate their quality.

As I am not very familiar with 'ed' usage, if you could show me the solution you would suggest for this thread as well as if you would point me a good link about it, i would really enjoy it.

Thanks again for your time sharing knowledge Smilie
# 13  
Old 04-01-2011
if you have tac installed, do this:
Code:
tac yourFile |sed '0,/AAA/{s/AAA/EEEE/}'|tac

# 14  
Old 04-01-2011
Quote:
Originally Posted by ctsgnb
As I am not very familiar with 'ed' usage, if you could show me the solution you would suggest for this thread as well as if you would point me a good link about it, i would really enjoy it.
Hi, ctsgnb:

My original post suggested ed, but ex is also a good option. If you already know vi, then you probably know quite a few ex commands (the colon commands in vi, but in ex you don't use the colon). Perhaps the following:
Code:
printf '%s\n' 1 '?AAA?s//EEEEE/' wq | ex -s file

ed is simpler than ex and behaves a little differently. In ed, entering nothing but a line number to make that line the current line also prints it (ex does not), so a redirect to /dev/null is probably a good idea to prevent unwanted text on stdout. Also, while ex always supports wq to write and quit, some eds do and some dont. The standard doesn't. So w and q should be specified as separate commands. Using ed:
Code:
printf '%s\n' 1 '?AAA?s//EEEEE/' w q | ed -s file > /dev/null

In ed/sed/ex, an empty regular expression is shorthand for the last regular expression used (whether in a previous substitution command or in an address).

There's also the heredoc option, of course, which is often the easiest of all to read (even though sometimes we all have an illogical inclination to squeeze everything into one line):
Code:
ed -s file >/dev/null <<'EOED'
1
?AAA?s//EEEEE/
w
q
EOED

As for a good source of info, I think the man pages and a terminal to play with is sufficient. ed is pretty simple. Off the top of my head, I'd say there are only about 15 commands to learn.

ed

Enjoy your weekend,
Alister
This User Gave Thanks to alister For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Find pattern and replace using sed

Hi, i want to replace the following lines in such a way that if the word merge exists in first column it must replace the 3rd column as M and if parse exists in first column then the last column must P, if neither it must mark it as X. I have tried the solution using awk, but it is saying... (6 Replies)
Discussion started by: charlie87
6 Replies

2. UNIX for Beginners Questions & Answers

sed replace pattern

I have a file with multiple lines, all in the same format. For each line, I need to replace the sequence of digits after the last : with a new value, but keep the single quote at the end of the line. Example: Input: ( two lines of file) Name: 'text1:200/text2:1.2.3.4' Name2:... (19 Replies)
Discussion started by: Beginner101
19 Replies

3. Shell Programming and Scripting

sed - Search and replace within pattern

Hi Guys! Unix newbie here! Have a requirement for which I have been scouting the forums for a solution but has been out of luck so far :( I have a file which contains the following:- TEST1|TEST2|"TEST3|1@!2"|TEST5 My sed command should result in either one the following output:-... (6 Replies)
Discussion started by: hishamzz
6 Replies

4. Shell Programming and Scripting

sed find/replace a pattern, but not this one..

I've got a file like so: ...lots of lines, etc. push "route 10.8.0.0 255.255.255.0" push "route 192.168.1.123 255.255.255.0" ...lots of lines, etc. I want to sed find/replace the IP address in the second line, whatever it is, with a new IP address, but I don't want to touch the first line.... (5 Replies)
Discussion started by: DaHai
5 Replies

5. Shell Programming and Scripting

sed command to replace two character pattern with another pattern

Not able to paste my content. Please see the attachment :-( (2 Replies)
Discussion started by: vivek d r
2 Replies

6. Shell Programming and Scripting

sed to replace pattern with filename

Hi all, I'm trying to replace a pattern/string in about 100 files with the filename using following commands but getting nowhere: for f in *.fa; do sed "s/^>.*/>$f/g" $f > $f_v1.fa; done for f in *.fa; do sed 's/^>.*/>`echo $f`/' > $fa_v1.fa; done Basically I want to change any line... (5 Replies)
Discussion started by: ivpz
5 Replies

7. Shell Programming and Scripting

Replace everything but pattern in a line using sed

I have a file with multiple lines like this: <junk><PATTERN><junk><PATTERN><junk> <junk><PATTERN><junk><PATTERN><junk><PATTERN><junk> Note that 1. There might be variable number occurrences of PATTERN in a line. 2. <> are just placeholders, they do not form part of the pattern. I need... (4 Replies)
Discussion started by: flatley
4 Replies

8. Shell Programming and Scripting

Pattern Replace using sed or awk

Hi , My file have data like 4:ALMOST NEVER PR 1925836 5:NEVER PR W DDA 5857610 6:NEVER PR WO DDA 26770205 but i want to replace the spaces before last numric digits out put should be like this 4:ALMOST NEVER PR=1925836 5:NEVER PR W DDA=5857610 6:NEVER PR WO... (7 Replies)
Discussion started by: max_hammer
7 Replies

9. Shell Programming and Scripting

SED Search Pattern and Replace with the Pattern

Hello All, I have a string "CP_STATUS OSSRC_R6_0_Shipment_R1H_CU AOM_901046 R1H_LLSV1_2008031", and I just want to extract LLSV1, but I dont get the expected result when using the sed command below. # echo "CP_STATUS OSSRC_R6_0_Shipment_R1H_CU AOM_901046 R1H_LLSV1_2008031" | awk '{print... (4 Replies)
Discussion started by: racbern
4 Replies

10. Shell Programming and Scripting

Find a pattern and replace using sed.

Hi I need to help on finding the below pattern using sed <b><a href="/home/document.do?assetkey=x-y-abcde-1&searchclause=photo"> and replace as below in the same line on the index file. <b><a href="/abcde.html"> thx in advance. Mari (5 Replies)
Discussion started by: maridhasan
5 Replies
Login or Register to Ask a Question