如何在 Awk 中使用单个正则表达式提取多个字符串

Lec*_*zyk 2 awk

我有以下字符串:

Mike has XXX cats and XXXXX dogs.
MikehasXXXcatsandXXXXXdogs
Run Code Online (Sandbox Code Playgroud)

我想用与 X 的数量相对应的数字替换 X:

我试过:

awk '{ match($0, /[X]+/);
  a = length(substr($0, RSTART, RLENGTH));
  gsub(/[X]+/, a) }1'
Run Code Online (Sandbox Code Playgroud)

但它只捕获第一场比赛。

预期输出:

Mike has 3 cats and 5 dogs.
Mikehas3catsand5dogs
Run Code Online (Sandbox Code Playgroud)

Rav*_*h13 5

使用您显示的样本,您能否尝试以下操作。在 GNU 中编写和测试awk(应该适用于任何awk)。

awk '{for(i=1;i<=NF;i++){if($i~/^X+$/){$i=gsub(/X/,"&",$i)}}} 1'  Input_file
Run Code Online (Sandbox Code Playgroud)

示例输出将是:

Mike has 3 cats and 5 dogs.
Run Code Online (Sandbox Code Playgroud)

说明:遍历所有字段(空格分隔)并检查字段是否从当前字段开始X并且只有X到当前字段的结尾,如果是,则全局替换它自己的值(以获取计数)并保存到当前字段本身。然后提到 1 将打印当前行。



注意:根据 Ed sir 的评论(在问题部分下),如果您的字段也可能有其他值,X那么请尝试(这甚至会涵盖XXX456任何列中的值):

awk '{for(i=1;i<=NF;i++){if($i~/X/){$i=gsub(/X/,"&",$i)}}} 1'  Input_file
Run Code Online (Sandbox Code Playgroud)

编辑:由于 OP 的示例已更改,因此在此处添加此解决方案,使用 GNU 编写和测试awk

awk -v RS='X+' '{ORS=(RT ? gsub(/./,"",RT) : "")} 1' Input_file
Run Code Online (Sandbox Code Playgroud)

或者

awk -v RS='X+' '{ORS=(RT ? length(RT) : "")} 1' Input_file
Run Code Online (Sandbox Code Playgroud)

上述代码的输出如下:

Mike has 3 cats and 5 dogs.
Mikehas3catsand5dogs
Run Code Online (Sandbox Code Playgroud)

  • 您还可以使用“length(RT)”代替“gsub”作为最后一个解决方案 (2认同)