LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-11-2010, 04:16 PM   #1
thefiend
LQ Newbie
 
Registered: Apr 2010
Posts: 2

Rep: Reputation: 0
Replace sequential numbers in a file with a different sequence using sed


Hello,

I am trying to find a way to replace a set of sequential numbers in a file with a different sequence using sed. This might be done easier using awk or some sort of bash script, but it seems to me there must be a way to do this easily with sed. Basically, what I am editing is a Cisco switch config. I want to change the sequence of ports to a different numbered sequence. Here is an example of what I am trying to do.

I want to change for example, the file:

Code:
cat testfile
interface FastEthernet0/1
 speed 10
 switchport access vlan 10
 spanning-tree portfast
!
interface FastEthernet0/2
 speed 10
 switchport access vlan 10
 spanning-tree portfast
!
interface FastEthernet0/3
 speed 100
 switchport access vlan 11
 spanning-tree portfast
!
interface FastEthernet0/4
 speed 10
 switchport access vlan 11
 spanning-tree portfast
To:

Code:
interface FastEthernet0/5
 speed 10
 switchport access vlan 10
 spanning-tree portfast
!
interface FastEthernet0/6
 speed 10
 switchport access vlan 10
 spanning-tree portfast
!
interface FastEthernet0/7
 speed 100
 switchport access vlan 11
 spanning-tree portfast
!
interface FastEthernet0/8
 speed 10
 switchport access vlan 11
 spanning-tree portfast
All that is being changed is the line "interface FastEthernet0/X" where X is the sequential value I want to change from 1-4 to 5-8.

I am fairly new to sed and linux in general, but I expected the replacement field in sed to also be able to handle a regular expression. However this command did not work:

cat testfile | sed 's/\/[1-4]/\/[5-8]/g'

This just replaces the FastEthernet0/X lines all with FastEthernet0/[5-8]. I have also tried the y/ switch in sed, which works for this example, but not for the full file I am trying to edit:

cat testfile | sed '/0\/[1-4]$/ y/[1234]/[5678]/'

This works, but I really want to replace the range 1-22 with 26-48, so this would be a really long sed statement:

cat testfile | sed '/0\/[1-22]$/ y/[123456789,10,11...]/[26,27,28,...]/'

Plus I have yet to figure out how to make y/ work with double digit entries.... so the above is probably a horrible example of y/.

Any help would really be appreciated, even if it is suggestions for awk or some sort of script.

Regards,

thefiend
 
Old 04-11-2010, 05:34 PM   #2
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
Hi, welcome to LQ!

Given that the ranges are crossing the ones/tens border I'd suggest awk
which can do some maths for you.
Something like this (quick and dirty):
Code:
/FastEthernet0/{
  new="0"gensub(/interface FastEthernet0\/(.*)/, "\\1","1",$0)
  print "interface FastEthernet0/"(new + 22)
  next
}
{
  print
}
 
Old 04-11-2010, 09:02 PM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,505

Rep: Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890
You could go a little simpler assuming the whole file looks as you have posted:

Code:
awk 'BEGIN{FS="/"}$0~FS{$2=$2+22}1' testfile
 
Old 04-12-2010, 12:28 AM   #4
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,067
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
Nice ... I was thinking way too complicated :}
 
Old 04-12-2010, 11:12 AM   #5
Kenhelm
Member
 
Registered: Mar 2008
Location: N. W. England
Distribution: Mandriva
Posts: 333

Rep: Reputation: 141Reputation: 141
This needs GNU sed and bash.
It uses the 's' command to replace the line in the pattern space with bash code made with back references, \1 and \2, to the line.
The GNU sed 'e' command executes the shell code found in the pattern space, replacing the code with the code's output.
Code:
sed -r 's|(interface FastEthernet0/)(.+)|echo \1$((\2+25))|e'

# Pattern space contents at each step
interface FastEthernet0/1               # Original line
echo interface FastEthernet0/$((1+25))  # bash code to be executed
interface FastEthernet0/26              # New line
 
Old 04-12-2010, 02:37 PM   #6
thefiend
LQ Newbie
 
Registered: Apr 2010
Posts: 2

Original Poster
Rep: Reputation: 0
Hello Everyone,

Thank you for the quick answers, I really appreciate it. This was my first post here. I always find answers here when searching google, so I figured I would sign up and contribute as best I can. Also, this particular question had me puzzled for a few days!

@Tinkster, thanks for the quick and dirty version

@grail, your solution was great too. However, I did have to adjust it a bit to get the result I wanted. Your example replaced the slash with a space:

Code:
awk 'BEGIN{FS="/"}$0FS{$2=$2+22}1' testfile
interface FastEthernet0 32
...
So I had to modify it (quick and dirty) with sed to replace the slash:

Code:
awk 'BEGIN{FS="/"}$0~FS{$2=$2+22}1' testfile | sed 's/t0 /t0\//g'
interface FastEthernet0/32
...
@Kenhelm, thank you so much for that one, I really felt like there must be a way to do this with sed. I was just starting to read about the back references and such, but was far from figuring it out. Your solution worked perfectly and uses sed, so I will mark this post as solved

Thank you!!

thefiend
 
Old 04-12-2010, 10:29 PM   #7
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,505

Rep: Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890Reputation: 2890
Nah ... it's much easier than that:
Code:
awk 'BEGIN{OFS=FS="/"}$0~FS{$2=$2+22}1' testfile
 
  


Reply


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
[SOLVED] sed command to replace file extension leighya Linux - Newbie 18 04-22-2012 03:20 AM
Problem using sed to replace string in file umk Debian 12 02-01-2012 08:39 AM
HOWTO convert a group of files in a directory to a set of sequential numbers? lleb Linux - General 7 12-24-2009 07:02 PM
Need a script to find/replace numbers with names in 1 file using another as the guide kmkocot Programming 4 07-03-2009 03:30 AM
sequence of numbers, how to extract which numbers are missing jonlake Programming 13 06-26-2006 03:28 AM


All times are GMT -5. The time now is 09:57 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration