【问题标题】:awk gensub regex backslash 0 and backslash 1 not Workingawk gensub 正则表达式反斜杠 0 和反斜杠 1 不工作
【发布时间】:2017-09-04 22:43:13
【问题描述】:

以下代码有效:

// {
print gensub("[a-z][A-Z]”,"&","g")
}

但这不是:

// {
print gensub("[a-z][A-Z]","\0","g")
}

这也不是我最终想要实现的目标:

// {
print gensub(“([a-z])([A-Z])",”\1 \2","g")
}

为什么这不起作用,我该如何使它起作用。这个脚本的目的:名字是用不以空格分隔的姓氏给出的,我需要将它们分开。 name 的第一个字符是大写字母,我不想在名字前有空格。我可以通过将FS 设置为'' 并检查每个字符来做到这一点,但我想学习 gensub。我也没有找到 gsub 的用法,因为它给了我匹配的数量,而不是替换后的字符串。

另一种可能的解决方案,但我不知道如何完成这项工作,是将 gensub 中的目标从 "g" 设置为 "2,3,4" 等,但我无法在这里给出多个论点。

请不要仅建议如何使上述其中一项工作的替代解决方案

【问题讨论】:

    标签: regex bash shell awk


    【解决方案1】:

    您在某些地方使用“智能引号”() 而不是真正的引号 ("),而 awk 反向引用是 \\1 等,而不仅仅是 \1。 gensub 的第一个参数也是正则表达式而不是字符串,因此请使用正则表达式分隔符 /.../ 而不是字符串分隔符 "..."(后者会导致双重解析,从而产生负面影响 - 请参阅手册页)。摆脱//s,因为它们只会弄乱你的代码。最后 - 使用字符类 [[:lower:]][[:upper:]] 而不是范围 [a-z][A-Z] 以获得可移植性和稳健性。

    $ echo 'EdMorton' | awk '{print gensub(/([[:lower:]])([[:upper:]])/,"\\1 \\2",1)}'
    Ed Morton
    

    【讨论】:

    • 如何更改智能报价和真实报价?你是怎么知道像 \\ 而不是 \ 这样的东西的?
    • idk 人们首先是如何创建“智能引号”的(我从您的问题中复制/粘贴)但我认为这与使用某些编辑器(也许是 Windows 的?)有关,所以也许找到不同的编辑器(我使用vi)?我以同样的方式了解其他一切——阅读文档和经验。 FWIW 我强烈推荐 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书——如果你还有其他 awk 书籍,那就扔掉吧。
    • 还有关于向 gensub 提供超过 1 个目标的问题。你能解决这个问题吗?我不知道你在说什么摆脱 // ?没有它们我的代码还能工作吗?
    • gensub() 不接受多个目标(如果我理解你的意思是第三个参数) - 它是一个数字或“g”。是的,您的代码将在没有空正则表达式的情况下工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    相关资源
    最近更新 更多