-2

Okay so I want to move all digits from end of the line to the front of the line, example of lines:

example123
example321
example2920

expected output:

123example
321example
2920example

the following sed command works to place numbers at the start to end -

sed -E 's/^([0-9]+)(.*)/\2\1/' file

input of this is

123example
321example

and output is

example123
example321

but when trying to do the same for numbers at the end moved to the front I can't seem to do it..

I've tried changing

^

to

$

and other things but I'm new to sed so I don't really understand alot.

Uni VPS
  • 99
  • 1
  • 9
  • This looks exactly same post as https://stackoverflow.com/questions/49335245/awk-bash-move-digits-from-front-of-line-to-end-of-line please refrain posting samething. – RavinderSingh13 Mar 18 '18 at 03:49

2 Answers2

3

The working example you give matches "a string of digits followed by anything". You might think that you could alter it to match "anything followed by some digits" (/\(.*\)\([0-9]*\)/), but the trouble is that sed matches as much as it can; in the working example it grabs as many digits as it can, and in the naive new version it grabs everything in the first term.

The trick is to match non-digits followed by anything:

sed 's/\([^0-9]*\)\(.*\)/\2\1/' filename

EDIT: I hadn't thought of the possibility of non-trailing digits. This:

sed 's/\(.*[^0-9]\)\(.*\)/\2\1/' filename

will turn

Ex1am2ple123

to

123Ex1am2ple
Beta
  • 96,650
  • 16
  • 149
  • 150
  • Problem with that is, if a line contains "Ex1am2ple123" I only want the ending digits to the front of the line, so in this example output would be 123Ex1am2ple – Uni VPS Mar 17 '18 at 22:09
  • @NoobLearning: I hadn't thought of that. I'll edit. (And yes, it informs me of all comments on my Answer.) – Beta Mar 17 '18 at 22:11
  • 1
    @Beta Try: `sed 's/\(.*[^[:digit:]]\)\([[:digit:]]*$\)/\2\1/'` – John1024 Mar 17 '18 at 22:13
  • @John1024: Thanks, but my solution is a little simpler. – Beta Mar 17 '18 at 22:17
  • 1
    Thank you @John1024 & Beta both solutions work, I have accepted your answer Beta, really appreciate the help :)! – Uni VPS Mar 17 '18 at 22:20
  • Btw, in order to be similar to the command style provided in the question (extended regexp) the answer can be rewritten as sed -E 's/(.*[^0-9])(.*)/\2\1/' file – Sergey Sargsyan Mar 17 '18 at 22:48
  • @SergeySargsyan: Good point. – Beta Mar 18 '18 at 01:06
1

Using GNU awk, you could match the trailing digits, and then print that, and a substring of the input, chopping off at the end the number of characters that were matched:

awk 'match($0, /[0-9]+$/, m) {print m[0] substr($0, 0, length($0) - length(m[0]))}' file

This solution works even if there are digits in the prefix, for example:

$ cat file
ex456le123
456mple321
example2920
$ gawk 'match($0, /[0-9]+$/, m) {print m[0] substr($0, 0, length($0) - length(m[0]))}' file
123ex456le
321456mple
2920example
janos
  • 120,954
  • 29
  • 226
  • 236
  • @jonas your answer worked as well as Beta's but I accepted his due to it being sed within the total, but I've +1'd your comment as it does work, so thank you for your help :) – Uni VPS Mar 17 '18 at 22:19
  • Any idea why this: `awk -F'[0-9]' '{print substr($0,length($1)+1) $1}' file` will need a `length($1)+1` ? – nbari Mar 17 '18 at 22:29