【问题标题】:Use sed to replace letters [a-z] and [A-Z] and ['] with underscores使用 sed 将字母 [a-z] 和 [A-Z] 和 ['] 替换为下划线
【发布时间】:2019-06-20 22:48:06
【问题描述】:

...对于除第一个单词之外的行中每个单词的第一个字母以外的所有字符。所有文本均为英文。

想使用 sed 来转换输入:

Mary had a little lamb
It's fleece was white as snow

到这里:

Mary h__ a l_____ l___
It's f_____ w__ w____ a_ s___

对于一个关注线索回忆的项目。

看了几篇关于 sed 和 regex 的介绍。将在 MacOS 10.14.5 附带的终端上使用 sed 的风格。

【问题讨论】:

  • 如果你可以使用 perl 你可以使用$str =~ s/^\S+\h+(*SKIP)(*FAIL)|(?!\b\S)\S/_/g;
  • sed -e ':a' -e 's/\([[:alpha:]]_*\)[[:alpha:]]/\1_/' -e 'ta' file > outfile,但还不是那么回事。
  • 单独使用 sed 将很难做到这一点,因为您真正需要的是积极的后视,这在 sed 中不受支持,即使使用 -E 开关也是如此。

标签: regex sed


【解决方案1】:

这可能对你有用(GNU sed):

sed -E 'h;y/'\''/x/;s/\B./_/g;G;s/\S+\s*(.*)\n(\S+\s*).*/\2\1/' file

在保留空间中复制当前行。将''s 翻译成`x's,这样这些词就可以用下划线而不是每个词的第一个字母来填充。附加复制的行,并使用分组和反向引用替换该行的第一个单词,不加修饰。

【讨论】:

  • 对我不起作用。它只是将每一行写入输出两次。
  • @WillisBlackburn MacOS 上的默认 sed 是 BSD sed,而不是 GNU sed。您必须安装 GNU sed 才能使用它。
  • 知道了。 OP 指定了 macOS sed。
【解决方案2】:

sed 用于对单个字符串执行简单的 s/old/new 操作,仅此而已。对于其他任何你应该使用 awk 的东西,例如使用 GNU awk 将第三个参数匹配():

$ awk '{
    out = $1
    $1 = ""
    while ( match($0,/(\S)(\S*)(.*)/,a) ) {
        out = out OFS a[1] gensub(/./,"_","g",a[2])
        $0 = a[3]
    }
    print out $0
}' file
Mary h__ a l_____ l___
It's f_____ w__ w____ a_ s___

在每个 UNIX 机器上的任何 shell 中使用任何 awk,包括 MacOS 上的默认 awk:

$ awk '{
    out = $1
    $1 = ""
    while ( match($0,/[^[:space:]][^[:space:]]*/) ) {
        str = substr($0,RSTART+1,RLENGTH-1)
        gsub(/./,"_",str)
        out = out OFS substr($0,RSTART,1) str
        $0 = substr($0,RSTART+RLENGTH)
    }
    print out $0
}' file
Mary h__ a l_____ l___
It's f_____ w__ w____ a_ s___

【讨论】:

    【解决方案3】:

    这是另一个awk 脚本(所有awk 版本),我喜欢为这个任务创作。

    script.awk

    {
        for (i = 2; i <= NF; i++) {    # for each input word starting from 2nd word
            head = substr($i,1,1);     # output word head is first letter from current field
            tail = substr("____________________________", 1, length($i) - 1); # output word tail is computed from template word
            $i = head tail;            # recreate current input word from head and tail
        }
        print;                         # output the converted line
    }
    

    input.txt

    Mary had a little lamb
    It's fleece was white as snow
    

    运行:

    awk -f script.awk input.txt
    

    这也可以压缩成一行:

    awk '{for (i = 2; i <= NF; i++) $i = substr($i,1,1) substr("____________________________", 1, length($i) - 1); print }' input.txt
    

    输出是:

    Mary h__ a l_____ l____
    It's f_____ w__ w____ a_ s___
    

    我喜欢这个任务。

    【讨论】:

      猜你喜欢
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      相关资源
      最近更新 更多