代码之家  ›  专栏  ›  技术社区  ›  Fábio Roberto Teodoro

进行各种替换,但仅限于角色之前

  •  0
  • Fábio Roberto Teodoro  · 技术社区  · 5 年前

    我在做这样的事情:

    echo 'foo_bar_baz=foo_bar_baz' | sed -r 's/_([[:alnum:]])/\U\1/g'
    

    结果是:

    fooBarBaz=fooBarBaz
    

    有没有办法 fooBarBaz=foo_bar_baz 相反

    我试着这么做,不贪婪:

    echo 'foo_bar_baz=foo_bar_baz' | sed -r 's/([^=].*?)_([[:alnum:]])/\1\U\2/g'
    

    但结果是:

    foo_bar_baz=foo_barBaz
    

    我需要的是转换成:

    foo_bar_baz=foo_bar_baz
    

    致:

    fooBarBaz=foo_bar_baz
    
    0 回复  |  直到 5 年前
        1
  •  5
  •   Fábio Roberto Teodoro    5 年前

    编辑: 添加更通用的解决方案,该解决方案在之前适用于3个以上的值 =

    awk '
    BEGIN{
      FS=OFS="="
    }
    {
      num=split($1,array,"_")
      for(i=2;i<=num;i++){
        val=(val?val:"")toupper(substr(array[i],1,1)) substr(array[i],2)
      }
      $1=array[1] val
      val=""
    }
    1
    '  Input_file
    


    对我来说,这应该是一项简单的任务 awk .

    echo 'foo_bar_baz=foo_bar_baz' | awk '
    BEGIN{
      FS=OFS="="
    }
    {
      split($1,array,"_")
      $1=array[1] toupper(substr(array[2],1,1)) substr(array[2],2) toupper(substr(array[3],1,1)) substr(array[3],2)
    }
    1'
    


    简单地移除 _ 在第一部分中使用(这不会使字母大写):

    echo 'foo_bar_baz=foo_bar_baz' | awk 'BEGIN{FS=OFS="="}{gsub(/_/,"",$1)} 1'
    
        2
  •  2
  •   Wiktor Stribiżew    5 年前

    你可以用

    s='foo_bar_baz=foo_bar_baz'
    sed -E ':a;s/^([^=_]*)_([[:alnum:]])/\1\U\2/g; ta' <<< "$s"
    # => fooBarBaz=foo_bar_baz
    

    看到了吗 online sed demo

    细节

    • :a -定义一个 a 如果替换成功,要跳转到的标签
    • s/^([^=_]*)_([[:alnum:]])/\1\U\2/g -找到
      • ^ -字符串开头
      • ([^=_]*) -第一组( \1 在替换模式中):除 = _
      • _ -下划线
      • ([[:alnum:]]) -第二组( \2 在替换模式中):字母数字字符
      • \1\U\2 -第一组值,然后是大写的第二组值
    • ta - t 是分支命令使sed返回到 A. 标记并重复匹配。
        3
  •  2
  •   potong    5 年前

    这可能适用于您(GNU-sed):

    sed -E 'h;s/_(.)/\u\1/g;G;s/=.*=/=/' file
    

    复制当前行。全部删除 _ 的和大写字母包含以下字符。附加副本并替换之间的所有内容 = 她和一个单身汉在一起 = .

    另一种选择:

    sed -E ':a;s/_(.*=)/\u\1/;ta' file 
    
        4
  •  1
  •   Ed Morton    5 年前

    第三个参数要匹配的GNU awk()

    $ echo 'foo_bar_baz=foo_bar_baz' |
      awk '{while (match($0,/(.*)_(.)(.*=.*)/,a)) $0 = a[1] toupper(a[2]) a[3]} 1'
    fooBarBaz=foo_bar_baz
    

    请注意,上述解决方案不限于任何特定数量的 _ 或下划线后的任何特定字母:

    $ echo 'wee_sleekit_cowrin_timrous_beastie=foo_bar_baz' |
      awk '{while (match($0,/(.*)_(.)(.*=.*)/,a)) $0 = a[1] toupper(a[2]) a[3]} 1'
    weeSleekitCowrinTimrousBeastie=foo_bar_baz
    

    改变 _(.) _([[:lower:]]) 如果您只想在后跟小写字母时删除下划线。