!/bin/bash

!/bin/bash

我正在尝试为大学做作业,但目前陷入困境。目标是读取一些电话号码并颠倒前 3 位数字的顺序并将它们放在括号中。我可以让它读取电话号码,但不能反转数字。

例如:输入

214 4234-5555

例如:输出

412 4234-5555

这就是我到目前为止所拥有的

sed -r "s/([0-9]), ([0-9]), ([0-9])/\3\2\1/g" phone.txt

答案1

修改OP的尝试

$ cat ip.txt
214 4234-5555
foo 123 4533-3242

$ sed -r 's/([0-9])([0-9])([0-9])/\3\2\1/' ip.txt
412 4234-5555
foo 321 4533-3242

$ # adding parenthesis as well
$ sed -r 's/([0-9])([0-9])([0-9])/(\3\2\1)/' ip.txt
(412) 4234-5555
foo (321) 4533-3242

$ # if ERE is not supported
$ sed 's/\([0-9]\)\([0-9]\)\([0-9]\)/(\3\2\1)/' ip.txt
(412) 4234-5555
foo (321) 4533-3242
  • 请注意,某些sed实现需要-E而不是-r
  • 除非需要插值,否则请使用单引号,另请参阅https://mywiki.wooledge.org/Quotes
  • ([0-9]), ([0-9]), ([0-9])表示匹配以逗号和空格分隔的 3 位数字
  • g如果要更改行中的所有匹配项,则需要修饰符


对于通用解决方案,即将要反转的位数定义为数字参数

$ perl -pe 's/\d{3}/reverse $&/e' ip.txt
412 4234-5555
foo 321 4533-3242
$ perl -pe 's/\d{3}/sprintf "(%s)", scalar reverse $&/e' ip.txt
(412) 4234-5555
foo (321) 4533-3242

答案2

这是一个很长、很复杂、可能没有必要的内容sed,但它仍然很有趣:

sed -re 'h;    s/^([0-9]*) *(.*)/\1\n/;  :1 s/(.)(.*\n)/\2\1/;t1;  s/.//;  s/^(.*)$/\(\1\)/; x;s/([0-9]{3})(.*)/\2/;x;G;s/\n//'

其工作原理如下:

      # pretend 214 4234-5555 is the current line
h;    # copy the current line into hold space
s/^([0-9]*) *(.*)/\1\n/;  # keep only first 3 numbers, 214
:1 s/(.)(.*\n)/\2\1/;t1;  s/.//;  # reversing string in sed, 
                                  # see notes below; 214 becomes 412
s/^(.*)$/\(\1\)/;  # After string is reversed, add brackets; (412)
x;s/([0-9]{3})(.*)/\2/; # swap hold and pattern buffer, 
                        # delete first 3 chars; 
                        # pattern space now is <space>4234-5555

x;G;s/\n// # swap again, append hold buffer to pattern buffer; 
            # now pattern buffer is (412)<newline> 4234-5555; 
            # finally delete newline; we get (412) 4234-5555

这就是它实际的样子:

$ printf "214 4234-5555\n123 3333\n" | sed -re 'h;    s/^([0-9]*) *(.*)/\1\n/;  :1 s/(.)(.*\n)/\2\1/;t1;  s/.//;  s/^(.*)$/\(\1\)/; x;s/([0-9]{3})(.*)/\2/;x;G;s/\n//'
(412) 4234-5555
(321) 3333

笔记:字符串反转最初发现于斯蒂芬·查泽拉斯的评论

答案3

方法1

我使用下面的方法得到相同的结果

i=`awk '{print $1}' example.txt| rev`
awk -v i="$i" '{print i,$2}' example.txt

输出

412 4234-5555

方法2

sed  's/\(.\)\(.\)\(.\)/\3\2\1/' example.txt

输出

412 4234-5555

答案4

如果您的phone.txt中的号码为“xxx xxx-xxxx”,那么您可以使用以下内容:

!/bin/bash

echo '('$(catphone.txt | cut -d ' ' -f1 | rev)')'

相关内容