【问题标题】:Format 11 digit numbers with sed and RegEx使用 sed 和 RegEx 格式化 11 位数字
【发布时间】:2021-08-01 05:49:15
【问题描述】:

我正在编写一个可以像这样转换数字(11 位)的脚本:

示例输入:

11111111111
12345678900

示例输出:

(11) 1 1111-1111
(12) 3 4567-8900

这是我正在使用的命令:

echo "$(sed 's/\(..\)\(.\{5\}\)/(\1)\2-/g' $file)"

但是输出是:

(11)11111-1111
(12)34567-8900

任何人都可以帮助我如何用空格隔离第三个数字作为示例输出?我只能使用 sed 和 RegEx。谢谢!

【问题讨论】:

  • 使用 GNU sed 朝着正确的方向前进:sed -E 's/(.{2})(.)(.{4})(.{4})/\1 \2 \3 \4/' file

标签: regex shell sed


【解决方案1】:

对于您展示的示例,您能否在此处尝试使用sed 的反向引用功能。

sed -E 's/^([0-9]{2})([0-9])([0-9]{4})([0-9]{4})$/(\1) \2 \3-\4/' Input_file

说明: 在此处使用-E 选项来使用带有sed 的扩展正则表达式。然后在这里使用sed 的反向引用功能。此处创建 4 个捕获组(其中分别有 2、1、4、4 个数字)。然后在替换它时,使用必要的字符串,例如 -> 在第一个捕获值之前和之后添加 () 等等,以使其与 OP 的要求相同。

【讨论】:

    【解决方案2】:
    sed -E 's/^(..)(.)(....)(.*)$/\(\1\) \2 \3\-\4/g' "file"
    

    【讨论】:

      【解决方案3】:

      在这里使用sed 和正则表达式似乎不必要地复杂。如果数字完全一致,只需打印添加了装饰的子字符串即可。

      awk 'BEGIN { split("(_) _ _-", f, /_/); split("2_1_4_4", l, /_/); }
      { n=1; for(i=1; i<=4; i++) {
          printf "%s%s", f[i], substr($1, n, l[i]); n+=l[i] }
        printf "\n" }' file
      

      BEGIN 块创建两个并行的数据结构来驱动脚本的主体。第一个f 包含要在子字符串的下一个切片之前添加的前缀,第二个l 包含我们要提取的子字符串的长度。

      如果你真的想让这个简单,你可以把它写成

      awk '{
          printf "(%s", substr($0, 1, 2);
          printf ") %s", substr($0, 3, 1);
          printf " %s", substr($0, 4, 4);
          printf "-%s\n", substr($0, 8);
      }' file
      

      正则表达式解决方案肯定更简洁,但在大多数情况下,拼写出来以便理解它们可能比符号紧凑性更重要。

      【讨论】:

        猜你喜欢
        • 2020-03-11
        • 2020-09-12
        • 2011-04-27
        • 2017-03-31
        • 1970-01-01
        • 2023-04-07
        • 2020-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多