![如何调换两个单词的首字母?](https://linux22.com/image/51721/%E5%A6%82%E4%BD%95%E8%B0%83%E6%8D%A2%E4%B8%A4%E4%B8%AA%E5%8D%95%E8%AF%8D%E7%9A%84%E9%A6%96%E5%AD%97%E6%AF%8D%EF%BC%9F.png)
$ echo 'foo bar' | sed SOMEMAGIC
boo far
$ echo 'one two' | sed SOMEMAGIC
tne owo
问:一般来说,如何将“bar”中的“b”替换为“foo”的“f”?反之亦然,将“foo”中的“f”替换为“bar”中的“b”。
答案1
您需要使用捕获组。捕获 (1) 单词的第一个字母,(2) 直到第二个单词的第一个字母的所有内容,(3) 第二个单词的第一个字母,然后交换 (3) 和 (1)。
在下面的示例中,假设该行以非空白字符开头
你可以说:
sed 's/\(.\)\([^ ]* \)\(.\)/\3\2\1/'
或者
sed -r 's/(.)([^ ]* )(.)/\3\2\1/'
例如,
$ echo 'foo bar' | sed -r 's/(.)([^ ]* )(.)/\3\2\1/'
boo far
$ echo 'one two' | sed -r 's/(.)([^ ]* )(.)/\3\2\1/'
tne owo
下面还可以处理行开头的空格以及两个单词之间有多个空格等情况:
sed -r 's/([^ ])([^ ]* +)(.)/\3\2\1/'
相应的 perl 表达式为:
perl -pe 's/(\S)(\S+\s+)(\S)/$3$2$1/'
例子:
$ echo 'one two' | perl -pe 's/(\S)(\S+\s+)(\S)/$3$2$1/'
tne owo
$ echo 'one two' | perl -pe 's/(\S)(\S+\s+)(\S)/$3$2$1/'
tne owo
$ echo 'foo bar' | perl -pe 's/(\S)(\S+\s+)(\S)/$3$2$1/'
boo far
$ echo ' one two' | perl -pe 's/(\S)(\S+\s+)(\S)/$3$2$1/'
tne owo
答案2
one=word ; two=phrase ; three=$one
one="${two%"${two#?}"}${one#?}"
two="${three%"${three#?}"}${two#?}"
echo "$one $two"
> pord whrase
答案3
一个可能的解决方案awk
:
echo 'foo bar' | awk '{x=substr($1,1,1); y=substr($2,1,1); sub(x, y, $1); sub(y, x, $2); print $0}'
boo far
这两个substr
函数调用将从每个记录中提取第一个字符,并且对sub
函数的两个调用将相互替换这些字符的第一次出现。
答案4
使用 sed:
echo 'one two' |sed -re 's/([^ ])([^ ]+)( +)([^ ])([^ ]+)/\4\2\3\1\5/'
tne owo
也匹配变量空间。