【问题标题】:Capitalize strings in sed or awk在 sed 或 awk 中将字符串大写
【发布时间】:2018-06-17 03:04:01
【问题描述】:

我想在 bash 脚本中大写三种类型的字符串。我认为 sed/awk 是我最好的选择,但我不确定。考虑到以下要求,最好的方法是什么?

  1. 单字
    例如taco -> Taco

  2. 用连字符分隔的多个单词
    例如my-fish-tacos -> My-Fish-Tacos

  3. 多个单词用下划线分隔
    例如my_fish_tacos -> My_Fish_Tacos

【问题讨论】:

    标签: bash sed awk


    【解决方案1】:

    没有必要使用捕获组(尽管& 在某种程度上是一个):

    echo "taco my-fish-tacos my_fish_tacos" | sed 's/[^ _-]*/\u&/g'
    

    输出:

    Taco My-Fish-Tacos My_Fish_Tacos
    

    转义的小写“u”将匹配的子字符串中的下一个字符大写。

    【讨论】:

    • 如何修改它以处理全大写的单词?例如 my-FISH-TACOS 应该输出 My-Fish-Tacos。
    • @GregB:告诉它把所有字符都小写,然后将下一个字符大写:sed 's/[^ _-]*/\L\u&/g'
    • 注意:这是一个 GNU sed 扩展。 BSD sed 用户(包括 OS X)不能这样做。
    • @DennisWilliamson 邀请您加入unix.stackexchange.com/questions/413562/…
    【解决方案2】:

    使用 awk:

    echo 'test' | awk '{
         for ( i=1; i <= NF; i++) {
             sub(".", substr(toupper($i), 1,1) , $i);
             print $i;
             # or
             # print substr(toupper($i), 1,1) substr($i, 2);
         }
    }'
    

    【讨论】:

    • 对上述示例的一点解释:NF - 内置 awk 变量来自字段数(通常显示一行中有多少个空格分隔的字符串) - 在这个例子中,它将返回 1 substr - 返回子字符串,声明看起来像这样 substr(string, start, length)sub - 替代函数 - sub(regex, replacement, target)
    • 注意:使用toupper(substr(... 可能比substr(toupper(... 更有效。
    【解决方案3】:

    尝试以下方法:

    sed 's/\([a-z]\)\([a-z]*\)/\U\1\L\2/g'
    

    它适用于我使用 GNU sed,但我认为 BSD sed 不支持 \U\L

    【讨论】:

      【解决方案4】:

      这是一个不使用\u 的解决方案,并非所有seds 都通用。

      将此文件保存到capitalize.sed,然后运行sed -i -f capitalize.sed FILE

      s:^:.:
      h
      y/qwertyuiopasdfghjklzxcvbnm/QWERTYUIOPASDFGHJKLZXCVBNM/ 
      G 
      s:$:\n:
      :r
      /^.\n.\n/{s:::;p;d}
      /^[^[:alpha:]][[:alpha:]]/ {
          s:.\(.\)\(.*\):x\2\1: 
          s:\n\(..\):\nx: 
          tr
      }
      
      /^[[:alpha:]][[:alpha:]]/ {
          s:\n.\(.\)\(.*\)$:\nx\2\1:
          s:..:x:
          tr
      }
      /^[^\n]/ {
          s:^.\(.\)\(.*\)$:.\2\1:
          s:\n..:\n.:
          tr
      }
      

      【讨论】:

        【解决方案5】:

        alinsoar 令人惊叹的解决方案在 Plan9 sed 中根本不起作用,在busybox sed 中也不正确。但是您仍然应该尝试弄清楚它应该如何做它的事情:您将学到很多关于 sed 的知识。

        这是一个不那么聪明但更容易理解的版本,它至少可以在 Plan9、busybox 和 GNU sed(可能还有 BSD 和 MacOS)中工作。 Plan9 sed 需要在s 命令的匹配部分中删除反斜杠。

        #! /bin/sed -f
        
        y/PYFGCRLAOEUIDHTNSQJKXBMWVZ/pyfgcrlaoeuidhtnsqjkxbmwvz/
        
        s/\(^\|[^A-Za-z]\)a/\1A/g
        s/\(^\|[^A-Za-z]\)b/\1B/g
        s/\(^\|[^A-Za-z]\)c/\1C/g
        s/\(^\|[^A-Za-z]\)d/\1D/g
        s/\(^\|[^A-Za-z]\)e/\1E/g
        s/\(^\|[^A-Za-z]\)f/\1F/g
        s/\(^\|[^A-Za-z]\)g/\1G/g
        s/\(^\|[^A-Za-z]\)h/\1H/g
        s/\(^\|[^A-Za-z]\)i/\1I/g
        s/\(^\|[^A-Za-z]\)j/\1J/g
        s/\(^\|[^A-Za-z]\)k/\1K/g
        s/\(^\|[^A-Za-z]\)l/\1L/g
        s/\(^\|[^A-Za-z]\)m/\1M/g
        s/\(^\|[^A-Za-z]\)n/\1N/g
        s/\(^\|[^A-Za-z]\)o/\1O/g
        s/\(^\|[^A-Za-z]\)p/\1P/g
        s/\(^\|[^A-Za-z]\)q/\1Q/g
        s/\(^\|[^A-Za-z]\)r/\1R/g
        s/\(^\|[^A-Za-z]\)s/\1S/g
        s/\(^\|[^A-Za-z]\)t/\1T/g
        s/\(^\|[^A-Za-z]\)u/\1U/g
        s/\(^\|[^A-Za-z]\)v/\1V/g
        s/\(^\|[^A-Za-z]\)w/\1W/g
        s/\(^\|[^A-Za-z]\)x/\1X/g
        s/\(^\|[^A-Za-z]\)y/\1Y/g
        s/\(^\|[^A-Za-z]\)z/\1Z/g
        

        【讨论】:

          【解决方案6】:

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

          echo "aaa bbb ccc aaa-bbb-ccc aaa_bbb_ccc aaa-bbb_ccc"  | sed 's/\<.\|_./\U&/g'
          Aaa Bbb Ccc Aaa-Bbb-Ccc Aaa_Bbb_Ccc Aaa-Bbb_Ccc
          

          【讨论】:

            猜你喜欢
            • 2019-09-16
            • 1970-01-01
            • 2022-01-27
            • 2011-08-13
            • 1970-01-01
            • 1970-01-01
            • 2012-10-15
            • 2020-02-18
            • 1970-01-01
            相关资源
            最近更新 更多