Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse four length of letters with sed in unix

Tags:

bash

unix

sed

How can I reverse a four length of letters with sed?

For example:

the year was 1815.

Reverse to:

the raey was 5181.

This is my attempt:

cat filename | sed's/\([a-z]*\) *\([a-z]*\)/\2, \1/'

But it does not work as I intended.

like image 549
Dante Avatar asked Feb 04 '23 04:02

Dante


2 Answers

not sure it is possible to do it with GNU sed for all cases. If _ doesn't occur immediately before/after four letter words, you can use

sed -E 's/\b([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])\b/\4\3\2\1/gi'

\b is word boundary, word definition being any alphabet or digit or underscore character. So \b will ensure to match only whole words not part of words

$ echo 'the year was 1815.' | sed -E 's/\b([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])\b/\4\3\2\1/gi'
the raey was 5181.
$ echo 'two time five three six good' | sed -E 's/\b([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])\b/\4\3\2\1/gi'
two emit evif three six doog

$ # but won't work if there are underscores around the words
$ echo '_good food' | sed -E 's/\b([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])\b/\4\3\2\1/gi'
_good doof


tool with lookaround support would work for all cases

$ echo '_good food' | perl -pe 's/(?<![a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])(?!=[a-z0-9])/$4$3$2$1/gi'
_doog doof

(?<![a-z0-9]) and (?!=[a-z0-9]) are negative lookbehind and negative lookahead respectively

Can be shortened to

perl -pe 's/(?<![a-z0-9])[a-z0-9]{4}(?!=[a-z0-9])/reverse $&/gie'

which uses the e modifier to place Perl code in substitution section. This form is suitable to easily change length of words to be reversed

like image 191
Sundeep Avatar answered Feb 08 '23 14:02

Sundeep


Possible shortest sed solution even if a four length of letters contains _s.

sed -r 's/\<(.)(.)(.)(.)\>/\4\3\2\1/g'
like image 27
αғsнιη Avatar answered Feb 08 '23 16:02

αғsнιη