I am trying to automate the swapping of characters 1 and 2, 3 and 4, etc, in a an arbitrary-length string of hex characters.





It seems like this should be possible using sed or one of the other *nix text utilities, but so far I have not been able to find any examples.


You can use back-references:

echo A627E39B | sed 's/\(.\)\(.\)/\2\1/g'

This finds all occurrences of two characters and swaps them.

As glenn jackman pointed out, enabling extended regular expressions (-E w/ GNU, BSD, or toybox seds) avoids having to escape the parentheses:

echo A627E39B | sed -E 's/(.)(.)/\2\1/g'
  • +1. A little tidier to use -r (or -E on BSDs) to avoid the escaped parens. – glenn jackman May 12 '15 at 1:19

There’s a tool that specifically, natively supports that function: dd with the swab (swap bytes) conversion:

% echo ABCD | dd conv=swab
0+1 records in
0+1 records out
5 bytes (5 B) copied, 0.000109277 s, 45.8 kB/s

You’ll want to add 2> /dev/null to discard the log output:

% echo ABCD | dd conv=swab 2> /dev/null

Warning: This will do pretty much what you want if you send it an even number of (printable) characters.  But, if you give it an odd number of printable characters — let’s say 2n+1 — then dd will take the newline at the end as the (2n+2)th character, and swap it with the (2n+1)th.  So,

% echo ABCDE | dd conv=swab 2> /dev/null


                A B C D E \n

to dd, which gives you

                B A D C \n E

back; this will look like


You can work around this by specifying the -n option to echo to suppress the newline at the end (or just use printf without adding a newline).  If you’re displaying the output to the screen, then, for completeness, you should add a newline at the very end:

% echo -n ABCDE | dd conv=swab 2> /dev/null; echo

% printf "%s" ABCDE | dd conv=swab 2> /dev/null; printf "\n"

You can also use perl:

$ echo A627E39B | perl -CLS -nle 'print map {~~reverse} unpack "(a2)*"'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.