Reverse order of dot-delimited elements in a string
Using combination of
tr
+tac
+paste
$ tr '.' $'\n' <<< 'arg1.arg2.arg3.arg4.arg5' | tac | paste -s -d '.' arg5.arg4.arg3.arg2.arg1
If you still prefer bash, you could do in this way,
IFS=. read -ra line <<< "arg1.arg2.arg3.arg4." let x=${#line[@]}-1; while [ "$x" -ge 0 ]; do echo -n "${line[$x]}."; let x--; done
Using
perl
,$ echo 'arg1.arg2.arg3.arg4.arg5' | perl -lne 'print join ".", reverse split/\./;' arg5.arg4.arg3.arg2.arg1
If you do not mind a tiny bit of python
:
".".join(s.split(".")[::-1])
Example:
$ python3 -c 's="arg1.arg2.arg3.arg4.arg5"; print(".".join(s.split(".")[::-1]))'
arg5.arg4.arg3.arg2.arg1
s.split(".")
generates a list containing.
separated substrings,[::-1]
reverses the list and".".join()
joins the components of the reversed list with.
.
You can do it with a single sed
invocation:
sed -E 'H;g;:t;s/(.*)(\n)(.*)(\.)(.*)/\1\4\5\2\3/;tt;s/\.(.*)\n/\1./'
this uses the hold buffer to get a leading newline in the pattern space and uses it to do permutations until the newline is no longer followed by any dot at which point it removes the leading dot from the pattern space and replaces the newline with a dot.
With BRE and a slightly different regex:
sed 'H
g
:t
s/\(.*\)\(\n\)\(.*\)\(\.\)\(.*\)/\1\4\5\2\3/
tt
s/\(\.\)\(.*\)\n/\2\1/'
If the input consists of more than one line and you want to reverse the order on each line:
sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/'