【问题标题】:Replace pattern by its length (portable solution for Bash)用长度替换模式(Bash 的便携式解决方案)
【发布时间】:2019-09-21 08:24:33
【问题描述】:

有没有办法用 Sed/Awk/Perl 用它的长度替换一个模式?我正在寻找可以在 Bash 脚本中使用的小型便携式命令。

我的字符串都以特定字符开头(比如说x),我想用它们的长度替换这些重复的x

所以

xxxx rest of the line
xxx again
xx again and again
xxxxx you got my point

会变成

4 rest of the line
3 again
2 again and again
5 you got my point

Sed 可能不是一个好的候选者。我知道 Perl 有一个 e 选项,它允许在替换字符串中执行代码,但我不确定在这里如何使用它:perl -pe 's/^(x+)/length($1)/e'?

【问题讨论】:

  • 好吧,看来我已经找到了解决方案。我编写的 Perl 命令正在运行。小心添加一个 awk 版本:) ?
  • 您的前导xs 后面是否总是有空格?是否总是领先xs?您是否关心每行未触及的空白?
  • 使用 bash:while read -r -a array; do array[0]="${#array[0]}"; echo "${array[@]}"; done < file
  • @EdMorton 是的,总是空间。我使用的字符是“组分隔符”\035。 @Cyrus 确实,简单而纯粹的 bash!但我担心大文件会有点太慢:)

标签: bash perl awk sed


【解决方案1】:

用它的长度替换第一个模式:

awk '$1=length($1)' file

输出:

其余 4 条线路 3再 2一次又一次 5 你明白我的意思

【讨论】:

  • 哇,这么简单。现在很明显 -_-' 因为我的行总是以重复的 x 开头,后跟一个空格,所以效果很好。
  • 这很容易,因为您使用 awk 的默认字段分隔符之一(空格或制表符)。
【解决方案2】:

它被标记为 perl,并且没有 perl 的解决方案,所以我将提供一个解决方案。

您的/e 走在正确的道路上

#!/usr/bin/env perl; 
use strict;
use warnings;
use Data::Dumper; 

while ( <DATA> ) {
    s/^(x+)/length $1/e;
    print;
}
__DATA__
xxxx rest of the line
xxx again
xx again and again
xxxxx you got my point

或者作为单行者:

perl -pe 's/^(x+)/length $1/e' file. 

【讨论】:

    【解决方案3】:

    这里是gawk 版本,但是您的 perl 解决方案更智能、更好。使用 gensub 函数将前导 xx.... 捕获到名为 first 的变量中。然后用它的长度替换第一列。

    awk '{first=gensub(/(^x+).*/,"\\1","g", $0);$1=length(first)}1' file
    4 rest of the line
    3 again
    2 again and again
    5 you got my point
    

    可以进一步缩短为:

    awk '{$1=length(gensub(/(^x+).*/,"\\1","g", $0))}1' file
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      • 2011-05-28
      • 2016-04-05
      • 2013-09-25
      • 2016-04-04
      • 1970-01-01
      相关资源
      最近更新 更多