LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-19-2020, 04:47 PM   #1
czezz
Member
 
Registered: Nov 2004
Distribution: Slackware/Solaris
Posts: 924

Rep: Reputation: 43
[BASH][SED] Find pattern and replace it's [pattern's] last character


Hi all,
Can anyone please give me a little help with sed here?

I have following example file:
Code:
cat test
blablalb A i B. E. lalalalal.
A. tralala,la A B i C.
B. elellfdew A. fww.
C. DiDweofjoie zalamki T.
Following grep will highlight the pattern that Im trying to change:
Code:
cat test | grep " i [A-Z][.]"   (mind the SPACE before "i")
So, eventually what Im trying to get is:
Code:
blablalb A i B, E. lalalalal.
A. tralala,la A B i C,
B. elellfdew A. fww.
C. DiDweofjoie zalamki T.
Normaly, if there was no pattern I would go for someting like this:
Code:
sed -e 's/ i [A-Z][.]/ i [A-Z][,]/g' test
sed -e '/ i [A-Z][.]/s//,/' test
Any ideas how to get it?

Last edited by czezz; 10-19-2020 at 05:51 PM.
 
Old 10-19-2020, 04:54 PM   #2
teckk
LQ Guru
 
Registered: Oct 2004
Distribution: Arch
Posts: 5,141
Blog Entries: 6

Rep: Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828Reputation: 1828
Code:
st="blablalb A i B. E. lalalalal.
A. tralala,la A B i C.
B. elellfdew A. fww.
C. DiDweofjoie zalamki T."

sed 's/\,/\./g' <<< "$st"
blablalb A i B. E. lalalalal.
A. tralala.la A B i C.
B. elellfdew A. fww.
C. DiDweofjoie zalamki T.
Or did I miss something.

Edit:You hightlighted/changed it while I was answering.

Last edited by teckk; 10-19-2020 at 05:01 PM.
 
Old 10-19-2020, 05:16 PM   #3
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,615

Rep: Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554

Don't think of it as "the last character", think of it as a pattern with two parts; you want to keep the first part and replace the second.

With Sed, you can use a capturing group around the first part, then reference it via its number in the replacement:
Code:
echo 'axbx' | sed -r 's/(a)x/\1y/'
With Perl, you have the additional option of using a lookbehind to match (but not replace) the first part:
Code:
echo 'axbx' | perl -pe 's/(?<=a)x/y/'
(The latter can be useful in situations where you already have capturing groups and don't want to renumber them.)


Last edited by boughtonp; 10-19-2020 at 05:22 PM.
 
2 members found this post helpful.
Old 10-19-2020, 05:28 PM   #4
czezz
Member
 
Registered: Nov 2004
Distribution: Slackware/Solaris
Posts: 924

Original Poster
Rep: Reputation: 43
Hi guys, thank you for your replies.
@teckk - sorry about that. I thought it would be useful to highlight patterns as its a tricky one.
@boughtonp - I tried to use my pattern " i [A-Z][.]" but that doesnt work. Thanks anyway for reply


Note: this is to replace . with , ONLY when dot stands next to capital letter followed by " i " (mind the spaces)
eg.
Code:
i B. >>>  i B,

Last edited by czezz; 10-19-2020 at 05:52 PM.
 
Old 10-19-2020, 07:24 PM   #5
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
With this InFile ...
Code:
blablalb A i B. E. lalalalal.
A. tralala,la A B i C.
B. elellfdew A. fww.
C. DiDweofjoie zalamki T.
... this sed ...
Code:
sed -r 's/(i [A-Z])(.)/\1\,/g' $InFile >$OutFile
... produced this OutFile ...
Code:
blablalb A i B, E. lalalalal.
A. tralala,la A B i C,
B. elellfdew A. fww.
C. DiDweofjoie zalamki T,
Daniel B. Martin

.
 
2 members found this post helpful.
Old 10-20-2020, 07:44 AM   #6
czezz
Member
 
Registered: Nov 2004
Distribution: Slackware/Solaris
Posts: 924

Original Poster
Rep: Reputation: 43
Thank you very much, Daniel

I did tiny modification to it as I need this SPACE before "i"
Code:
sed -r 's/( i [A-Z])(.)/\1\,/g'
 
Old 10-20-2020, 07:56 AM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,910

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
that is still not ok.
But first: you cannot use a regexp in the right side (replacement string), because there is no string to match. You need to specify the replacement string itself.
If you want to specify dot (.) you must use [.] (or \.), not (.) as regexp, and you need not use \ in the replacement string before the comma (but \1 is ok, because it has a special meaning).
 
1 members found this post helpful.
Old 10-20-2020, 10:32 AM   #8
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,805

Rep: Reputation: 1206Reputation: 1206Reputation: 1206Reputation: 1206Reputation: 1206Reputation: 1206Reputation: 1206Reputation: 1206Reputation: 1206
With -r or -E option the left side is ERE (extended regular expression), where ( ) is a capture group.
Code:
sed -r 's/( i [A-Z])[.]/\1,/g' test
Without -r or -E option the left side is BRE (basic regular expression), where \( \) is a capture group.
Code:
sed 's/\( i [A-Z]\)[.]/\1,/g' test
The right side is the substitution string, where \1 is what the 1st capture group matched.

Last edited by MadeInGermany; 10-20-2020 at 10:43 AM.
 
1 members found this post helpful.
Old 10-21-2020, 07:27 PM   #9
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
OP asked for a sed solution and now has one. As a learning exercise I worked up an awk solution.

With this InFile ...
Code:
blablalb A i B. E. lalalalal.
A. tralala,la A B i C.
B. elellfdew A. fww.
C. DiDweofjoie zalamki T.
... this awk ...
Code:
awk '{if (n=match($0,/ i [A-Z]\./)) 
        {before=substr($0,n,5)
         after=substr($0,n,4)","
         sub(before,after)}
     }1' $InFile >$OutFile
... produced this OutFile ...
Code:
blablalb A i B, E. lalalalal.
A. tralala,la A B i C,
B. elellfdew A. fww.
C. DiDweofjoie zalamki T.
Corrections and improvements are always welcomed.

Daniel B. Martin

.

Last edited by danielbmartin; 10-21-2020 at 07:28 PM.
 
Old 10-22-2020, 01:10 AM   #10
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,910

Rep: Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318Reputation: 7318
you can do the same gensub in awk (quite similar to the sed solution)
Code:
awk ' { print gensub("( i [A-Z])\.", "\\1", "g" } '
(not tested, this is just the idea)
 
1 members found this post helpful.
Old 10-22-2020, 07:43 AM   #11
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
Quote:
Originally Posted by pan64 View Post
you can do the same gensub in awk (quite similar to the sed solution)
Code:
awk ' { print gensub("( i [A-Z])\.", "\\1", "g" } '
(not tested, this is just the idea)
Excellent! With minor mods ...
Code:
awk '{print gensub("( i [A-Z])\\.", "\\1,", "g")}' $InFile >$OutFile
... this works nicely. {Tested.}

Love those one-line solutions!

Daniel B. Martin

.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
using grep and sed to find and replace a string with a pattern (HELP) bengerman Linux - Newbie 5 07-03-2013 12:53 PM
Find and Replace character/special character from the file MyRelam Red Hat 8 05-21-2012 12:52 AM
[SOLVED] /bin/bash if statement pattern search, end of pattern special character? headhunter_unit23 Programming 3 04-29-2010 08:05 AM
Sed scripting "how to replace value for only last part of a pattern " alok.rhct Linux - General 3 04-28-2010 07:10 AM
Replace 2nd to last Character with SED elproducto Programming 5 03-31-2009 12:41 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:00 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration