walt
walt

Reputation: 33

SED - reverse matched pattern

I have the following task:

match all lines which end with a number and then reverse these numbers

example:

romarana:qwerty12543
asdewfpwk:asdqwe312
asdj:asbd
asdewfpwk:strwtwe129
ooasodo:asbdjahj

should be:

romarana:qwerty34521
asdj:asbd
asdewfpwk:asdqwe213
asdewfpwk:strwtwe921
ooasodo:asbdjahj

What I tried:

sed -r "/[0-9]$/s/[0-9]{1,}$/$(rev <<< &)/" test.txt

NOTE: you can ignore lines that don't end with the number for now.

NOTE: You can use awk,grep or any other tool

Upvotes: 1

Views: 2856

Answers (5)

Ed Morton
Ed Morton

Reputation: 204721

With GNU awk for the 3rd arg to match() and null FS splitting $0 into chars:

$ awk -v FS= 'match($0,/(.*[^0-9])([0-9]+)$/,a) {
    $0=a[2]; for (i=NF;i>=1;i--) a[1]=a[1] $i; $0=a[1]
} 1' file
romarana:qwerty34521
asdewfpwk:asdqwe213
asdj:asbd
asdewfpwk:strwtwe921
ooasodo:asbdjahj

Upvotes: 2

Sundeep
Sundeep

Reputation: 23707

With perl

$ perl -pe 's/\d+$/reverse $&/e' ip.txt
romarana:qwerty34521
asdewfpwk:asdqwe213
asdj:asbd
asdewfpwk:strwtwe921
ooasodo:asbdjahj

The e modifier allows to use Perl code in replacement section. $& contains the matched portion.

Upvotes: 8

RavinderSingh13
RavinderSingh13

Reputation: 133770

With GNU awk could you please try following.

awk '
match($0,/[0-9]+$/,a){
  num=split(a[0],arr,"")
  for(i=num;i>0;i--){
    val=val arr[i]
  }
  print substr($0,1,RSTART-1) val
  val=""
  next
}
1
' Input_file

Output will be as follows.

romarana:qwerty34521
asdewfpwk:asdqwe213
asdj:asbd
asdewfpwk:strwtwe921
ooasodo:asbdjahj

Upvotes: 2

Armali
Armali

Reputation: 19415

This can also be done with sed alone, by inserting a separator character (let's take the number sign) before the number and then repeatedly moving the line's last digit before the separator:

sed 's/\([0-9]*\)$/#\1/;:b;s/#\([0-9]*\)\([0-9]\)$/\2#\1/;tb;s/#$//'

Upvotes: 2

paxdiablo
paxdiablo

Reputation: 882756

You can do this with an awk command, as in the following bash script:

#!/usr/bin/env sh

(   echo romarana:qwerty12543
    echo asdewfpwk:asdqwe312
    echo asdj:asbd
    echo asdewfpwk:strwtwe129
    echo ooasodo:asbdjahj ) | awk '
        /[0-9]+$/ {                             # Lines ending in digits.
            num = txt = $0                      # Divide into text and num.
            gsub("[0-9]+$", "", txt)
            num = substr(num, length(txt)+1)

            revnum = ""                         # Build reversed number bit.
            while (num != "") {
                revnum = substr(num, 1, 1)""revnum
                num = substr(num, 2)
            }

            print txt""revnum" (from "$0")"     # Output text, reversed num.
            next
        }
        { print }                               # Not digits at end.
    '

It's pretty verbose, and could probably be reduced, but it does the job (you can get rid of the from output, that's just there so you can see it's working):

pax:~> ./testprog.sh
romarana:qwerty34521 (from romarana:qwerty12543)
asdewfpwk:asdqwe213 (from asdewfpwk:asdqwe312)
asdj:asbd
asdewfpwk:strwtwe921 (from asdewfpwk:strwtwe129)
ooasodo:asbdjahj

Upvotes: 2

Related Questions