How would someone use sed to go about reordering groups of substrings within a string separated by commas?
For instance,
hello bob, my name is, joseph
becomes:
joseph, My name is, hello bob
With this as the test file:
$ cat file
hello bob, my name is, joseph
We can reorder the fields as you like with:
$ sed -E 's/([^,]*), *([^,]*), *([^,]*)/\3, \2, \1/' file
joseph, my name is, hello bob
A sed substitute command has the form s/old/new/. This replaces old with new where old is a regex. In this case, old is:
([^,]*), *([^,]*), *([^,]*)
The items in parens are groups. This separates the line into three comma-separated groups. We can refer to these three groups as \1, \2, and \3 respectively. In the new text, then, we use:
\3, \2, \1
This reverses the order of the groups, putting the third first and the first last, as you requested.
If we want to reverse all the substrings but the number of substrings is unknown in advance, then awk is a good tool to use:
$ awk -F', *' '{for (i=NF;i>0;i--)printf "%s%s",$i,(i>1?", ":"\n")}' file
joseph, my name is, hello bob
-F', *' indicates that we want to use a comma optionally followed spaces as the field delimiter.
for (i=NF;i>0;i--)printf "%s%s",$i,(i>1?", ":"\n") loops in reverse over each field and prints it followed either by , or, for the last one, a newline.
Here is an example of reversing words within a substring:
$ sed -E 's/([^ ,]*) ([^,]*), /\2 \1, /' file
bob hello, my name is, joseph
Here is an example of reversing the words within a substring while also reversing substring order:
$ sed -E 's/([^ ,]*) ([^,]*), *([^,]*), *([^,]*)/\4, \3, \2 \1/' file
joseph, my name is, bob hello
awk. See updated answer for the awk code.You can also use awk :
awk -F', ' '{ print $3 ", " $2 ", " $1 }' <<< "hello bob, my name is, joseph"
#joseph, my name is, hello bob
Update:
Based on @andlrc's comment, this solution is simpler:
awk 'BEGIN{FS=OFS=", "}{print $3, $2, $1}' <<< "hello bob, my name is, joseph"
awk 'BEGIN{FS=OFS=", "}{print $3, $2, $1}', this way you don't need to hardcode , 3 times