Bash 如何交换一行中的第一个数字和最后一个数字?

Bash 如何交换一行中的第一个数字和最后一个数字?,bash,shell,unix,sed,Bash,Shell,Unix,Sed,我想交换第一个数字和最后一个数字,但这样做时,我得不到正确的输出 echo 1234jj h777 jj89 | sed 's/^\([0-9]\{1,\}\)\(.*\)\([0-9]*\{1,\}\)$/\3\2\1/' 我得到的输出是: 9jj h777 jj81234 预期产出: 89jj h777 jj81234 为什么不考虑89作为数字(只考虑9)?下面的sed可能会对您有所帮助 echo "1234jj h777 jj89" | sed 's/\([^a-z]*\)\([^

我想交换第一个数字和最后一个数字,但这样做时,我得不到正确的输出

echo 1234jj h777 jj89 | sed 's/^\([0-9]\{1,\}\)\(.*\)\([0-9]*\{1,\}\)$/\3\2\1/'
我得到的输出是:

9jj h777 jj81234
预期产出:

89jj h777 jj81234

为什么不考虑89作为数字(只考虑9)?

下面的
sed
可能会对您有所帮助

echo "1234jj h777 jj89" | sed 's/\([^a-z]*\)\([^ ]*\) \([^ ]*\) \([^0-9]*\)\([0-9]*\)/\5\2 \3 \4\1/g'
编辑:现在也添加非线性形式的解决方案

echo "1234jj h777 jj89" | sed '
s/\([^a-z]*\) \
\([^ ]*\) \
\([^ ]*\) \
\([^0-9]*\) \
\([0-9]*\) \
/\5\2 \3 \4\1/g'
这可能适用于您(GNU-sed):

或直接:

sed 's/^\([[:digit:]][[:digit:]]*\)\(.*[^[:digit:]]\)\([[:digit:]][[:digit:]]*\)$/\3\2\1/' file
诀窍是使用贪婪来吞掉数字的数字,第一个数字是好的,第二个数字是多余的。通过用前面的非数字锚定第二个数字的开头,可以捕获数字,然后重新排列。

POSIX外壳:

输出:

89jj h777 jj1234


注意:对于大型输入文件,这将比sed慢。只需一两行就可以更快,因为不需要加载
sed

为什么您想要的结果(
89jjh777 jj81234
)比您的输入(
1234jjh777 jjj89
)长一个字符?我想您的预期输出是
89jj777 jjJ1234
(8不重复)。我们需要更多的解释。你的“数字”总是用空格隔开吗?你需要颠倒数字和字母吗?JJ89VS 89JJ?它认为代码>8 <代码>是一个数字。但是,
*
是贪婪的,它将所有内容匹配到最后一位。您还应该指定这样的输入应该发生什么:
12345
。如果输入以字母结尾,请指定输出。例如,假设输入为
1a2a
。如果输出为
a2a1
1a2a
?如果输入为
12
,则会失败-它输出
12
,(而不是
21
)。@agc,谢谢agc,但我已按照OP的要求提供了解决方案,如果我遗漏了什么,请务必告诉我。我将删除我的答案。请不要删除它,Q不是那么清楚,因为我们绝对确定OP想要什么。看见
echo 1234jj h777 jj89 | 
{ read x ; h=${x##*[^0-9]} t=${x%%[^0-9]*} x="${x#$t}" x="${x%$h}" ;
  echo "$h$x${x:+$t}";}
89jj h777 jj1234