3

I have a file like this -

   !
   interface csa2549abA
   xxxx
   yyyy
   zzzz
   !
   interface aso23apwoeAe
   aaa
   bbb
   ccc
   !
   interface FastEthernet0/1
   ppp
   qqq
   rrr
   !

and so on.

What I want is to rename the interfaces that look like hashes to something more coherent but not the ones that makes sense and make the output like this. The key difference between ones that makes sense and the ones that don't is that the ones that are hashes have numbers in between the name. The ones that make sense always end with numbers. The output should look like this -

   !
   interface ethernet1
   xxxx
   yyyy
   zzzz
   !
   interface ethernet2
   aaa
   bbb
   ccc
   !
   interface FastEthernet0/1
   ppp
   qqq
   rrr
   !

and so on. Each interface is just an increment on the values of the ethernet term. Also assume that there are multiple files each of this type which can be taken as input.

What I have right now is sed -i 's/^interface .*$/interface Ethernet/' * but this just replaces the values of every interface value with Ethernet. I was wondering if there was a command to just increment the last part of Ethernet to represent something like I want.

4

Since arithmetic is required, sed is not the right tool. The solution below uses awk.

Answer for revised question

You say the unwanted hashes always have names that include a number followed by a letter. In that case:

$ awk '/^interface .*[[:digit:]][[:alpha:]]/{$0="interface ethernet" ++f} 1' file1
!
interface ethernet1
xxxx
yyyy
zzzz
!
interface ethernet2
aaa
bbb
ccc
!
interface FastEthernet0/1
ppp
qqq
rrr
!

How it works:

  • /^interface .*[[:digit:]][[:alpha:]]/

    This selects only those lines that start with interface and which also later include a number followed by a letter.

  • $0="interface ethernet" ++f

    The lines selected as above are changed to interface ethernet and a number and the number is incremented each time.

  • 1

    This is awk's cryptic shorthand for print-the-line.

To change the file in-place, assuming that you are using a modern GNU awk, use:

awk -i inplace '/^interface .*[[:digit:]][[:alpha:]]/{$0="interface ethernet" ++f} 1' file1

Answer for original question

$ awk '/^interface /{$0="interface ethernet" ++f} 1' file
!
interface ethernet1
xxxx
yyyy
zzzz
!
interface ethernet2
aaa
bbb
ccc
!

To change the file in-place and assuming a modern GNU awk, use:

awk -i inplace '/^interface /{$0="interface ethernet" ++f} 1' file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.