LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
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 06-25-2017, 12:50 PM   #1
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 292

Rep: Reputation: Disabled
[Solved] Search & Replace exact string with sed


Lets say that you have a file called sample.txt
and inside that file are these texts :

john
paul
#will
smith

Now the normal procedure to replace an exact string with sed is :

Quote:
sed 's/\<find\>/replace/g' < oldfile > newfile
Now if i want to change in that text above the #will to will with sed , i am unable to do it the normal way because the # symbol .

code that do not work :
Quote:
sed 's/\<#will\>/will/g' < sample.txt > sample.tmp
Anyone knows how to bypass this issue ?

Last edited by pedropt; 06-25-2017 at 02:33 PM.
 
Old 06-25-2017, 01:01 PM   #2
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 23,658

Rep: Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913
Quote:
Originally Posted by pedropt View Post
Lets say that you have a file called sample.txt
and inside that file are these texts :

john
paul
#will
smith

Now the normal procedure to replace an exact string with sed is :
Code:
sed 's/\<find\>/replace/g' < oldfile > newfile
Now if i want to change in that text above the #will to will with sed , i am unable to do it the normal way because the # symbol . code that do not work :
Code:
sed 's/\<#will\>/will/g' < sample.txt > sample.tmp
Anyone knows how to bypass this issue ?
You do, since you posted it already. Put a "" in front of the #, just like you did for the <>'s.
 
Old 06-25-2017, 01:02 PM   #3
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.8.2003
Posts: 5,384

Rep: Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021Reputation: 2021
Quote:
Originally Posted by pedropt View Post
Now if i want to change in that text above the #will to will with sed , i am unable to do it the normal way because the # symbol .

code that do not work :


Anyone knows how to bypass this issue ?
Escape the # ?
Code:
sed 's/\<\#will\>/will/g' < sample.txt > sample.tmp
 
Old 06-25-2017, 01:08 PM   #4
Laserbeak
Member
 
Registered: Jan 2017
Location: Manhattan, NYC NY
Distribution: Mac OS X, iOS, Solaris
Posts: 508

Rep: Reputation: 143Reputation: 143
I'm not that familiar with using sed, but can't you just use a backslash to escape the '#' sign?

It works in Perl:

Code:
#!/usr/bin/perl

foreach (<>) {

  s/\#//;
  print;
}
Usage:

Code:
./sometext.pl < sometext.txt
john
paul
will
smith
 
Old 06-25-2017, 01:12 PM   #5
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,814

Rep: Reputation: 639Reputation: 639Reputation: 639Reputation: 639Reputation: 639Reputation: 639
With this InFile ...
Code:
john
paul
#will
smith
... this sed ...
Code:
sed 's/#will/will/' $InFile >$OutFile
... produced this OutFile ...
Code:
john
paul
will
smith
Daniel B. Martin
 
1 members found this post helpful.
Old 06-25-2017, 01:13 PM   #6
Laserbeak
Member
 
Registered: Jan 2017
Location: Manhattan, NYC NY
Distribution: Mac OS X, iOS, Solaris
Posts: 508

Rep: Reputation: 143Reputation: 143
sed should work too:

Code:
echo '#will' | sed 's/\#//'
will
 
Old 06-25-2017, 01:36 PM   #7
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 292

Original Poster
Rep: Reputation: Disabled
Quote:
With this InFile ...
Code:

john
paul
#will
smith

... this sed ...
Code:

sed 's/#will/will/' $InFile >$OutFile

... produced this OutFile ...
Code:

john
paul
will
smith
eventually it will work if you only got #will in the text .
but if you get in that list also #williams and you only want to change #will then it will not work .
The thing is that "exact match" must be used in this case.

Quote:
sed 's/\<\#will\>/will/g' < sample.txt > sample.tmp
this one does not change the file

Last edited by pedropt; 06-25-2017 at 01:37 PM.
 
Old 06-25-2017, 01:38 PM   #8
TB0ne
LQ Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 23,658

Rep: Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913Reputation: 6913
Quote:
Originally Posted by pedropt View Post
eventually it will work if you only got #will in the text .
but if you get in that list also #williams and you only want to change #will then it will not work .


this one does not change the file
Why not, exactly??? Changing the "will" in william to "will" in william is a zero-sum change. You're replacing the exact string...unless you tell it to replace "william" with "will", it won't look one bit different, but just remove the #. Based on what you posted, you've got your solution.

If you don't...then why don't you post an actual piece of your input file, along with detailed requirements and what you've written so far. We can't guess. If the big issue here is the # sign, just remove it....
Code:
sed 's/\#//g'
Done.

Last edited by TB0ne; 06-25-2017 at 01:40 PM.
 
1 members found this post helpful.
Old 06-25-2017, 01:41 PM   #9
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 292

Original Poster
Rep: Reputation: Disabled
Quote:
You do, since you posted it already. Put a "" in front of the #, just like you did for the <>'s.
Post an example of the code .
 
Old 06-25-2017, 01:50 PM   #10
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=14, FreeBSD_12{.0|.1}
Posts: 5,583
Blog Entries: 11

Rep: Reputation: 3606Reputation: 3606Reputation: 3606Reputation: 3606Reputation: 3606Reputation: 3606Reputation: 3606Reputation: 3606Reputation: 3606Reputation: 3606Reputation: 3606
Quote:
Originally Posted by pedropt View Post
Code:
sed 's/\<\#will\>/will/g' < sample.txt > sample.tmp
this one does not change the file
No it doesn't, because there is no string matching '<#will>' in the file.

Why are you wrapping '#will' with '<...>'? You seem to think this has some special universal significance other than simply matching those characters - it does not (maybe GNU extension?). It does not mean "exact match" in all regular expressions as you seem to imply.

To match only '#will' and not '#william', use regular expression syntax, this:

Code:
sed 's/^#will$/will/' < sample.txt > sample.tmp

Last edited by astrogeek; 06-25-2017 at 02:35 PM. Reason: Added exact expression, elaboration
 
Old 06-25-2017, 02:09 PM   #11
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (current), FreeBSD, Win10, It varies
Posts: 9,952

Rep: Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148Reputation: 2148
Code:
userx%slackwhere ⚡ ~ ⚡> echo "#will" | sed 's/\#//'
will
userx%slackwhere ⚡ ~ ⚡> echo "#will" | sed 's/\#will/will/'
will
userx%slackwhere ⚡ ~ ⚡>
seems these two ways work then if you add the $ to keep it just 'will' well then there ya go.
Code:
userx%slackwhere ⚡ ~ ⚡> echo "#william" | sed 's/\#will$/will/'
#william
userx%slackwhere ⚡ ~ ⚡>
 
Old 06-25-2017, 02:18 PM   #12
Laserbeak
Member
 
Registered: Jan 2017
Location: Manhattan, NYC NY
Distribution: Mac OS X, iOS, Solaris
Posts: 508

Rep: Reputation: 143Reputation: 143
Oh, I didn't understand exactly what you meant.

Then, in Perl, you'd do this:

Code:
#!/usr/bin/perl

foreach (<>) {

  s/^\#(will)$/$1/;
  print;
}
so using this file:

Code:
john
paul
#will
smith
#william
will#iam
#otherwills
#wil
You'd get this output:

Code:
 ./sometext.pl < sometext.txt
john
paul
will
smith
#william
will#iam
#otherwills
#wil
Is that not what you want?
 
Old 06-25-2017, 02:22 PM   #13
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,149

Rep: Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523Reputation: 1523
An universal solution would escape every characters of 'From' and 'To' This could be achieved with sed:
Code:
FromE=$(printf '%s' "$From" | sed 's/./\\&/g')
ToE=$(printf '%s' "$To" | sed 's/./\\&/g')
sed "s/$FromE/ToE/"
 
Old 06-25-2017, 02:27 PM   #14
Laserbeak
Member
 
Registered: Jan 2017
Location: Manhattan, NYC NY
Distribution: Mac OS X, iOS, Solaris
Posts: 508

Rep: Reputation: 143Reputation: 143
So to make it short, you could make it a one-liner:

Code:
root@sunshine:~# perl -e  'for (<>) {s/^\#(will)$/$1/; print}' < sometext.txt
john
paul
will
smith
#william
will#iam
#otherwills
#wil
root@sunshine:~#
 
Old 06-25-2017, 02:32 PM   #15
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 292

Original Poster
Rep: Reputation: Disabled
Quote:
sed 's/^\#will$/will/' < sample.txt > sample.tmp
Nice one Astrogeek , this one works perfectly .
thanks for the help on this one .

Thanks to all other alternatives , i forgot to mention , but i wanted this code using only bash language .
 
  


Reply

Tags
sed


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
sed search for a string, duplicate original and replace the string Jykke Programming 17 06-29-2016 10:14 AM
sed: search for string, then match and replace the next occurance of a word nbritton Programming 4 01-21-2015 12:40 PM
[SOLVED] search and replace string with special character perl or sed. Noobux Programming 4 05-21-2012 03:16 PM
[SOLVED] sed: global search and replace if a string isn't anywhere in that line linux_kung_fu Linux - General 5 03-09-2012 10:53 AM

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

All times are GMT -5. The time now is 03:46 AM.

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