如何交换字符串中每两个字符对的顺序?

如何交换字符串中每两个字符对的顺序?

我正在尝试在任意长度的十六进制字符字符串中自动交换字符 1 和 2、3 和 4 等。

例子:

A627E39B

变成:

6A723EB9

看起来这应该可以使用 sed 或其他 *nix 文本实用程序之一来实现,但到目前为止我还没有找到任何示例。

答案1

您可以使用反向引用:

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

这会找到所有出现的两个字符并交换它们。

作为格伦·杰克曼指出,启用扩展正则表达式(-Ew/ GNU、BSD 或toybox seds) 避免必须转义括号:

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

答案2

有一个工具本身专门支持该功能: dd使用swab(西南瓦pytes)转换:

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

您需要添加2> /dev/null以丢弃日志输出:

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

警告:如果您发送偶数个(可打印)字符,这将几乎满足您的要求。但是,如果你给它奇数个可打印字符——假设 2 个n+1 — 然后dd将末尾的换行符作为 (2n+2)字符,并将其与第 (2) 个字符交换n+1)。所以,

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

发送

                A B C D E \n

dd,这给了你

                B A D C \n E

后退;这看起来像

BADC
E

您可以通过指定在末尾抑制换行符的-n选项(或者仅使用而不添加换行符)来解决此问题。如果您要将输出显示到屏幕上,那么为了完整起见,您应该在最后添加换行符:echoprintf

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

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

答案3

您还可以使用perl

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

相关内容