【问题标题】:Linux search and replace a patterns case within a stringLinux 搜索和替换字符串中的模式大小写
【发布时间】:2015-06-26 08:44:51
【问题描述】:

一直在努力想办法做到这一点。基本上我需要在代表 uri 的字符串中将 {} 中包含的 anything 的大小写从下到上更改(并且还去掉大括号,但我可以使用 sed 来做到这一点)

例如

/logs/{server_id}/path/{os_id}

/logs/SERVER_ID/path/OS_ID

字符串其余部分的大小写必须保留在较低的位置,这是一直困扰我的地方。到目前为止,用正则表达式查看了 sed、awk、tr 的组合。任何帮助表示赞赏。

【问题讨论】:

  • 应该将{SERVER{ONE}_ID} 替换为SERVERONE_ID 还是保持内括号不变? (即SERVER{ONE}_ID
  • 嗨,亚历杭德罗,内托也应该去掉。谢谢

标签: regex awk sed


【解决方案1】:
 sed "s/{\([^{}]*\)}/\U\1/g"

这是通过匹配 {} 中包含的所有文本并将其替换为大写版本来实现的。

echo "/logs/{server_id}/path/{os_id}" | sed "s/{\([^{}]*\)}/\U\1/g"

给出/logs/SERVER_ID/path/OS_ID 作为结果。

【讨论】:

    【解决方案2】:
    echo "/logs/{server_id}/path/{os_id}" \
    | sed 's#{\([^{}][^{}]*\)}#\U\1#;s#{\([^{}][^{}]*\)}#\U\1#'
    

    输出

    /logs/SERVER_ID/path/OS_ID
    

    您似乎错过的部分解决方案是 sed 中可用的“捕获组”,即\(regex\)。然后由\1 引用。如果你是一个真正的受虐狂,你可以从1-9 捕获组;-)

    另外请注意,我只是重复相同的 cmd 2 次,因为第一个 {...} 对已转换为 UC 版本(没有包围 {}s),因此只有剩余的 {...} 目标将匹配。

    [^{}][^{}* 的可用语法可能不那么冗长,但这适用于任何回到 80 年代的 sed。我似乎记得有些seds 不支持\U 指令,但是对于我可以访问的系统,这是可行的。

    这有帮助吗?

    【讨论】:

      【解决方案3】:
      $ awk '{
            while(match($0,/{[^}]+}/)) 
                $0=substr($0,1,RSTART-1) toupper(substr($0,RSTART+1,RLENGTH-2)) substr($0,RSTART+RLENGTH)
      }1' file
      /logs/SERVER_ID/path/OS_ID
      

      【讨论】:

        【解决方案4】:

        这个处理任意数量和格式的大括号:

        echo "/logs/{server_id}/path/{os_id}/{foo}" | awk -v RS='{' -v FS='}' -v ORS='\0' -v OFS='\0' '!/}/ { print } /}/ { $1 = toupper($1); print}'
        

        输出:

         /logs/SERVER_ID/path/OS_ID/FOO
        

        【讨论】:

          猜你喜欢
          • 2015-03-19
          • 1970-01-01
          • 1970-01-01
          • 2021-05-31
          • 1970-01-01
          • 2015-05-26
          • 1970-01-01
          相关资源
          最近更新 更多