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

时间:2018-01-07 11:46:43

标签: 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)?

3 个答案:

答案 0 :(得分:1)

这可能适合你(GNU sed):

sed -r 's/^([0-9]+)(.*[^0-9])([0-9]+)$/\3\2\1/' file 

或者用缩写:

sed 's/^\([[:digit:]][[:digit:]]*\)\(.*[^[:digit:]]\)\([[:digit:]][[:digit:]]*\)$/\3\2\1/' file

诀窍是使用贪婪.*吞噬一个数字的数字,这在第一个数字中是好的但在第二个数字中是过多的。通过将第二个数字的开头锚定前一个非数字,可以捕获数字然后重新排列。

答案 1 :(得分:0)

关注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'

答案 2 :(得分:0)

POSIX shell:

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

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