If you have Office 365 Excel then use This array formula:
=TEXTJOIN(",",,TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),((LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1)-ROW(
1:INDEX(XFD:XFD,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1)))*99+1,99)))
Being an array formula it needs to be confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode.
If one does not have Office 365 Excel then vba will probably be the only choice.

If you have Office 365 Excel then use This array formula:
=TEXTJOIN(",",,TRIM(MID(SUBSTITUTE(A2,",",REPT(" ",99)),((LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1)-ROW(
1:INDEX(XFD:XFD,LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1)))*99+1,99)))
Being an array formula it needs to be confirmed with Ctrl-Shift-Enter instead of Enter when exiting edit mode.
If one does not have Office 365 Excel then vba will probably be the only choice.

Sloppy UDF solution:
Function REVERSESTRING(original As Range, delim As String)
Dim i As Long, reversed As String, arr As Variant
arr = Split(original.Value, delim)
For i = UBound(arr) To 0 Step -1
reversed = reversed & arr(i) & ","
Next i
REVERSESTRING = Left(reversed, Len(reversed) - 1)
End Function

Via regex:
:s/\v([^, ]+)(\s*,\s*)([^, ]+)/\3\2\1/
If you do it often you can make a map out of it, e.g.:
:nmap <F5> :s/\v([^, ]+)(\s*,\s*)([^, ]+)/\3\2\1/<CR>
Put the cursor on the line you want to flip and hit F5.
This one swaps the word your cursor is on with the next one - just press F9 in command mode:
:map <F9> "qdiwdwep"qp
- "qdiw: Put the word your cursor is on into buffer 'q'
- dw: Delete all chars to the beginning of the next word (possibly comma + space)
- e: Go to end of word
- p: Paste (comma + space)
- "qp: Paste buffer 'q' (the first word)
Here I do it with sed:
sed '/,/!b
s/\( *[^ ]*\)\(.*\)/\2,\n\1/;:t
s/\([^,]*,\)\(\n.*\)/\2\1/;tt
s/\n\(.*\),/\1/' <<\DATA
LABEL1
.BYTE 01, 02, 03, 04, 05
.BYTE 01, 02, 03
LABEL1
.BYTE 01, 02, 03, 04, 05
.BYTE 01, 02, 03
DATA
OUTPUT
LABEL1
.BYTE 05, 04, 03, 02, 01
.BYTE 03, 02, 01
LABEL1
.BYTE 05, 04, 03, 02, 01
.BYTE 03, 02, 01
It checks for a comma on the current line. If there is !no comma, sed branches out of the script and autoprints the line. If the line does contain a comma sed does the following:
- It first prepares the line by
s///ubstituting the following:\( *[^ ]*\)- the first occurring sequence of zero or more spaces followed immediately by a sequence of zero or more not space characters referenced as\1followed immediately by...\(.*\)- everything else on the line referenced as\2...- ...with
\2,\n\1 - Note - using the
\nescape in the right-hands///ubstitution field like this is not fully portable. For asedthat does not support it, it can be done instead by substituting a literal newline for thenin the statement.
- It
:defines a branch/test label calledt. - While it still can,
seds///ubstitutes:\([^,]*,\)- A sequence of zero or more not comma characters then a single comma referenced as\1followed immediately by...\(\n.*\)- A sequence beginning with at least one\newline character followed by anything/everything remaining in pattern space referenced as\2...- ...with
\2\1.
- If the previous
s///ubstitutiontests successful,sedbranches back to the:test label and tries again. - Last
seddoes a little cleanup and replaces:\n\(.*\),- the first occurring\newline character and the last occurring comma...\1- ...with all that lies between.
As sed does the recursive replacement, the \newline delimiter walks backwards one comma-delimited field at a time. It stops the replacements when the \newline is the first character on the line. Here's a look at its progress through the recursive replacement process:
01, 02, 03, 04, 05,\n .BYTE$
01, 02, 03, 04,\n .BYTE 05,$
01, 02, 03,\n .BYTE 05, 04,$
01, 02,\n .BYTE 05, 04, 03,$
01,\n .BYTE 05, 04, 03, 02,$
\n .BYTE 05, 04, 03, 02, 01,$
After its initial preparatory substitution, sed does not delimit on anything but commas and the inserted \newline character. So any kind of comma-separated values work fine. Here's the output from running your long bit through it:
ITINERARY_ARRAY_01
.BYTE <ITINERARY_00A
.BYTE <ITINERARY_01A
.BYTE <ITINERARY_02A
.BYTE <ITINERARY_03A
.BYTE <ITINERARY_04A
.BYTE <ITINERARY_05A
.BYTE <ITINERARY_06A
.BYTE <ITINERARY_07A
.BYTE <ITINERARY_08A
.BYTE <ITINERARY_09A
.BYTE <ITINERARY_10A
.BYTE <ITINERARY_11A
.BYTE <ITINERARY_12A
.BYTE <ITINERARY_13A
.BYTE <ITINERARY_14A
;-------------------
ITINERARY_01E
.BYTE $00, $07, $05, $03
;-------------------
ITINERARY_01F
.BYTE $00, $09, $07, $05, $03
;-------------------
ITINERARY_01G
.BYTE $00, $0D, $28
;-------------------
ITINERARY_01H
.BYTE $00, $13, $0F, $0D, $28
;-------------------
ITINERARY_01I
.BYTE $00, $11, $0F, $0D, $28
;-------------------
ITINERARY_01J
.BYTE $00, $1E, $20, $09, $07, $05, $03
;-------------------
ITINERARY_01K
.BYTE $00, $15, $13, $0F, $0D, $28
;-------------------
ITINERARY_01L
.BYTE $27, $1C, $1E, $20, $09, $07, $05, $03
.BYTE $00
;---------------------
File revbytes2.awk:
#!/usr/bin/awk -f
BEGIN {
FS=",? +"
}
NF>2 && match($0,"^ +\.BYTE ") {
printf substr($0,1,RSTART+RLENGTH-1)
for(i=NF;i>3;i--) printf $i", "
print $3
next
}
1
FS=",? +" makes awk recognise the space after .BYTE and the , plus space sequence between the bytes as field separator.
For each line this will look for lines with more than 2 fields starting with spaces followed by .BYTE and one space and rember the start and length of this prefix in RSTART and RLENGTH as side effect of the match(...) expression.
If this match is found and there are more than 2 fields, the prefix is cut from the original line using RSTART and RLENGTH and printed followed by the remaining fields in reverse order.
If the spaces plus .BYTE plus space prefix was not found or there were not more than 2 fields, the line will be printed as is. So this will be done for a .BYTE-line defining only one byte too, because there is nothing to reverse.
Test run:
$ diff -u$(wc -l <input) input <(awk -f revbytes2.awk input)
--- input 2014-10-19 06:04:48.280714146 +0200
+++ /dev/fd/63 2014-10-19 22:40:01.385538235 +0200
@@ -1,42 +1,42 @@
ITINERARY_ARRAY_01
.BYTE <ITINERARY_00A
.BYTE <ITINERARY_01A
.BYTE <ITINERARY_02A
.BYTE <ITINERARY_03A
.BYTE <ITINERARY_04A
.BYTE <ITINERARY_05A
.BYTE <ITINERARY_06A
.BYTE <ITINERARY_07A
.BYTE <ITINERARY_08A
.BYTE <ITINERARY_09A
.BYTE <ITINERARY_10A
.BYTE <ITINERARY_11A
.BYTE <ITINERARY_12A
.BYTE <ITINERARY_13A
.BYTE <ITINERARY_14A
;-------------------
ITINERARY_01E
- .BYTE $03, $05, $07, $00
+ .BYTE $00, $07, $05, $03
;-------------------
ITINERARY_01F
- .BYTE $03, $05, $07, $09, $00
+ .BYTE $00, $09, $07, $05, $03
;-------------------
ITINERARY_01G
- .BYTE $28, $0D, $00
+ .BYTE $00, $0D, $28
;-------------------
ITINERARY_01H
- .BYTE $28, $0D, $0F, $13, $00
+ .BYTE $00, $13, $0F, $0D, $28
;-------------------
ITINERARY_01I
- .BYTE $28, $0D, $0F, $11, $00
+ .BYTE $00, $11, $0F, $0D, $28
;-------------------
ITINERARY_01J
- .BYTE $03, $05, $07, $09, $20, $1E, $00
+ .BYTE $00, $1E, $20, $09, $07, $05, $03
;-------------------
ITINERARY_01K
- .BYTE $28, $0D, $0F, $13, $15, $00
+ .BYTE $00, $15, $13, $0F, $0D, $28
;-------------------
ITINERARY_01L
- .BYTE $03, $05, $07, $09, $20, $1E, $1C, $27
+ .BYTE $27, $1C, $1E, $20, $09, $07, $05, $03
.BYTE $00
;---------------------
Comparing mawk and gawk output:
$ diff <(mawk -f revbytes2.awk input) <(gawk -f revbytes2.awk input)
gawk: revbytes2.awk:5: warning: escape sequence `\.' treated as plain `.'
Obvioisly no differences on stdout. Good!
The warning vanishes if you write "^ +\056BYTE " instead of "^ +\.BYTE " inside the match(...) expression.
Maybe someone using gawk frequently knows a better way to avoid the warning.
You can do this with awk:
#!/bin/bash
awk 'BEGIN{FS=",[ ]*"; OFS=", "}
{
for (i=NF; i>0; i--) {
printf "%s", $i;
if (i>1) {
printf "%s", OFS;
}
}
printf "\n"
}'
Explanation of the script:
FS=",[ ]*";: The regex for Field Separator (delimiter for your input) matches a comma followed by zero or more spaces, so your input can be any of:a, b, c, 1337, d, ea,b,c,1337,d,ea, (many spaces) b, c,1337,d, e
OFS=", ": The Output Field Separator (delimiter for your output) will be explicitly a comma followed by a space (so output looks consistent)for (i=NF; i>0; i--) { ... }:NFmeans the Number of Fields in the current line. Here we iterate backwards, printing from the last field to the first field.if (i>1) { ... }: Only print theOFSif it's not the last field in the outputprintf "\n": new line.
Sample usage:
$ ./script_name < input_file > output_file
If your input is simple, and the number of columns is static, you could always go with a hardcoded awk solution:
awk -F, '{ print $6", "$5", "$4", "$3", "$2", "$1 }'
This assumes that you have 6 columns that are separated by a comma. If you have a "comma + space" delimiter, ,, you can use -F', ' instead of just -F,.
A straightforward example usage with output:
$ echo "a, b, c, 1337, d, e" | awk -F', ' '{ print $6", "$5", "$4", "$3", "$2", "$1 }'
e, d, 1337, c, b, a
With a file as input:
awk -F', ' '{ print $6", "$5", "$4", "$3", "$2", "$1 }' your_file
You can then redirect the output from that to another file by appending > reversed_columns; "reversed_columns" being the name of the new file in this case.