【问题标题】:Replace non-alphanumeric characters in substring替换子字符串中的非字母数字字符
【发布时间】:2017-07-09 03:43:47
【问题描述】:

我正在尝试将一组键值对的第一部分(= 符号之前)中存在的任何非字母数字字符替换为 _:

输入

aa:cc:dd=foo-bar|17657V70YPQOV
ee-ff/gg=barFOO

期望的输出

aa_cc_dd=foo-bar|17657V70YPQOV
ee_ff_gg=barFOO

我尝试过诸如s/\([^a-zA-Z]*\)=\(.*\)/\1=\2/g 之类的模式,但没有取得多大成功。任何基本的 GNU/Linux 工具都可以使用。

【问题讨论】:

    标签: regex awk sed tr


    【解决方案1】:

    与awk

    $ awk -F= -v OFS='=' '{gsub("[^a-zA-Z]", "_", $1)} 1' ip.txt 
    aa_cc_dd=foo-bar|17657V70YPQOV
    ee_ff_gg=barFOO
    

    输入和输出字段分隔符设置为=,然后gsub("[^a-zA-Z]", "_", $1) 将仅将第一个字段的所有非字母字符替换为_


    与perl

    $ perl -pe 's/^[^=]+/$&=~s|[^a-z]|_|gir/e' ip.txt 
    aa_cc_dd=foo-bar|17657V70YPQOV
    ee_ff_gg=barFOO
    
    • ^[^=]+ 非 = 行首字符
    • $&=~s|[^a-z]|_|gir 仅将匹配部分的非字母字符替换为 _
    • 使用perl -i -pe 进行就地编辑

    【讨论】:

      【解决方案2】:

      假设您的输入位于名为 infile 的文件中,您可以这样做:

      while IFS== read key value; do
          printf '%s=%s\n' "${key//[![:alnum:]]/_}" "${value}"
      done < infile
      

      输出

      aa_cc_dd=foo-bar|17657V70YPQOV
      ee_ff_gg=barFOO
      

      这会将IFS 变量设置为=,并将您的键/值对逐行读取到key 和value 变量中。

      printf 命令打印它们并将= 添加回; "${key//[![:alnum:]]/_}" 将 key 中的所有非字母数字字符替换为下划线。

      【讨论】:

        【解决方案3】:

        任何符合Posix 的awk

        $ cat f
        aa:cc:dd=foo-bar|17657V70YPQOV
        ee-ff/gg=barFOO
        
        $ awk 'BEGIN{FS=OFS="="}gsub(/[^[:alnum:]]/,"_",$1)+1' f
        aa_cc_dd=foo-bar|17657V70YPQOV
        ee_ff_gg=barFOO
        

        说明

        BEGIN{FS=OFS="="}设置输入输出字段分隔符=

        /[^[:alnum:]]/匹配列表中不存在的字符, [:alnum:] 匹配字母数字字符 [a-zA-Z0-9]

        gsub(REGEXP, REPLACEMENT, TARGET) 这类似于sub 函数,除了gsub 替换 所有个最长、最左边、不重叠的匹配 它可以找到的子字符串。 gsub中的g代表全局,表示处处替换,gsub函数返回数字 换人次数

        +1 每当 gsub 返回 0 时,它都会处理默认操作 {print $0}

        【讨论】:

          【解决方案4】:

          我想我会扔一点红宝石:

          ruby -pe '$_.sub!(/[^=]+/){|m| m.gsub(/[^[:alnum:]]/,"_")}'
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-10-10
            • 2012-09-04
            • 2010-12-20
            • 1970-01-01
            • 1970-01-01
            • 2018-11-25
            • 2013-07-18
            • 2012-05-31
            相关资源
            最近更新 更多