LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
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 02-05-2013, 08:27 AM   #1
jmvidalvia
LQ Newbie
 
Registered: Mar 2011
Posts: 23

Rep: Reputation: 0
SED: replace all coincidences only from a position upto another


Hi,
I am getting crazy with an apparently simple problem.
As an example, need to change all "x" into "y" from the 5th position up tp the 10th.
Code:
Source: xbcb1xbx4b5x
Output: xbcb1yby4b5x
Thanks!

Last edited by jmvidalvia; 02-05-2013 at 10:07 AM.
 
Old 02-05-2013, 09:11 AM   #2
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
[/code]
#!/usr/bin/perl -w

$_=<>;
($first,$middle,$last)=/^(.{4})(.{6})(.*)/;
$middle =~ s/x/y/g;
printf("%s%s%s\n", $first,$middle,$last);
[/code]
 
1 members found this post helpful.
Old 02-05-2013, 09:33 AM   #3
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 jmvidalvia View Post
... need to change all "x" into "y" from the 5th position up to the 10th.
Code:
Source: xbcb1xbx4b5x
Output: xbcb1yby4b5x
Thanks!
Difficult to do with sed alone.
Easier with awk.
Code:
awk -F "" 'OFS="";{for (j=5;j<=10;j++) if ($j=="x") $j="y"}'1 <<< 'xbcb1xbx4b5x'
Daniel B. Martin

Last edited by danielbmartin; 02-05-2013 at 10:03 AM. Reason: Tighten the code, slightly
 
1 members found this post helpful.
Old 02-05-2013, 10:06 AM   #4
jmvidalvia
LQ Newbie
 
Registered: Mar 2011
Posts: 23

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by danielbmartin View Post
Difficult to do with sed alone.
Easier with awk.
Code:
awk -F "" 'OFS="";{for (j=5;j<= 10;j++) if ($j=="x") $j="y"}'1
Daniel B. Martin
Thanks! Works great.
I am facing an unexpected need: same file but with variable fields tab separated instead of fixed width.
I can not use the lenght because of the variable size of every field, and need to "count" fields, in order to replace "x" for "y" in fields from #2 to #8.
Thanks!

PS: will mark as solved as the original question in fact is.
 
Old 02-05-2013, 10:12 AM   #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
Quote:
Originally Posted by jmvidalvia View Post
I am facing an unexpected need: same file but with variable fields tab separated instead of fixed width.
I can not use the length because of the variable size of every field, and need to "count" fields, in order to replace "x" for "y" in fields from #2 to #8.
Please provide a sample input file and a corresponding output file. Tell which character separates fields (blank, tab, etc.).

Daniel B.Martin
 
Old 02-05-2013, 10:40 AM   #6
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 jmvidalvia View Post
I am facing an unexpected need: same file but with variable fields tab separated instead of fixed width.
I can not use the length because of the variable size of every field, and need to "count" fields, in order to replace "x" for "y" in fields from #2 to #8.
To replace all "e" with "E" in blank-delimited fields 2 through 8, try this ...
Code:
awk -F" " '{for (j=2;j<=8;j++) gsub("e","E",$j)}'1 $Raven > $OutFile
This awk produces output like this ...
Code:
'Prophet!' said I, 'thing of Evil! - prophEt still, if bird or devil!
By that HEavEn that bEnds abovE us - by that God we both adore -
Tell this soul with sorrow ladEn if, within the distant Aidenn,
It shall clasp a saintEd maidEn whom thE angels named Lenore -
Clasp a rarE and radiant maidEn, whom thE angels named Lenore?'
Quoth thE ravEn, 'NEvErmorE.'
Daniel B. Martin
 
1 members found this post helpful.
Old 02-05-2013, 10:46 AM   #7
jmvidalvia
LQ Newbie
 
Registered: Mar 2011
Posts: 23

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by danielbmartin View Post
Please provide a sample input file and a corresponding output file. Tell which character separates fields (blank, tab, etc.).

Daniel B.Martin
Sorry.
The sample input and output files would be something like:
Code:
input: abcd▸   exg▸  hxjk▸  lmxop▸  qrst¬
output: abcd▸   exg▸  hyjk▸  lmyop▸  qrst¬
(field separator is \t)

I found the following to work, but just for one field (#3 in the example).

Code:
awk -F'\t' -vOFS='\t' '{ gsub("x", "y", $3) ; print }' file > file1
Need to learn how to iterate the number of field to get "from one to another", 3 to 5 in the example.
Thanks,.
 
Old 02-05-2013, 11:12 AM   #8
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 jmvidalvia View Post
Need to learn how to iterate the number of field to get "from one to another", 3 to 5 in the example.
Try this ...
Code:
awk 'OFS="\t" {for (j=3;j<=5;j++) gsub("x","Y",$j)}'1 $InFile > $OutFile
Daniel B. Martin
 
1 members found this post helpful.
Old 02-05-2013, 01:29 PM   #9
jmvidalvia
LQ Newbie
 
Registered: Mar 2011
Posts: 23

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by danielbmartin View Post
Try this ...
Code:
awk 'OFS="\t" {for (j=3;j<=5;j++) gsub("x","Y",$j)}'1 $InFile > $OutFile
Daniel B. Martin
Perfect: thank you very much.

EDIT: had to add -F'\t' though

Last edited by jmvidalvia; 02-05-2013 at 02:23 PM.
 
Old 02-05-2013, 04:11 PM   #10
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
This can be done in sed with a hold space. Here's what you need to do:
  • Copy pattern space to hold space.
  • Strip the first five characters.
  • Do the desired transformation.
  • Exchange pattern space and hold space.
  • Strip everything but the first five characters.
  • Append hold space to pattern space.
  • Replace new line characters with nothing.
  • You're done.

EDIT: Ah, if you are interested in only 5..10 characters than it's a bit different but again can easily be done with hold space as so:
  • Copy pattern to hold space.
  • Strip everything but characters 5-10.
  • Perform desired transformation.
  • Append hold space to pattern space.
  • Do s/\(.*\)\n\(.....\).....\(.*)/\2\1\3/ (not tested and there may be more magic required if not all lines are guaranteed to be ≥ 10 characters).

Last edited by mina86; 02-05-2013 at 04:15 PM.
 
  


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
Insert multiple lines in specificic position with sed or awk micronemo Linux - Newbie 4 09-13-2012 06:27 AM
[SOLVED] replace specific position with sed nushki Programming 6 01-27-2012 04:36 AM
[SOLVED] SED search and replace fields in a fixed position based on a condition. jfkse7en Programming 7 01-06-2012 06:14 AM
Using sed/awk to replace a string at a given position in anoopvraj Linux - Newbie 6 05-30-2009 07:59 AM
Spacing out on simple sed task: find position of substring in a variable? lumix Linux - General 2 10-16-2008 03:07 PM

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

All times are GMT -5. The time now is 04:18 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