Regex 替换子字符串中的非字母数字字符

Regex 替换子字符串中的非字母数字字符,regex,awk,sed,tr,Regex,Awk,Sed,Tr,我试图用一个\uu替换一组键值对的第一部分(在=符号之前)中存在的任何非字母数字字符: 输入 aa:cc:dd=foo-bar|17657V70YPQOV ee-ff/gg=barFOO aa_cc_dd=foo-bar|17657V70YPQOV ee_ff_gg=barFOO 所需输出 aa:cc:dd=foo-bar|17657V70YPQOV ee-ff/gg=barFOO aa_cc_dd=foo-bar|17657V70YPQOV ee_ff_gg=barFOO 我曾尝试过这

我试图用一个
\uu
替换一组键值对的第一部分(在
=
符号之前)中存在的任何非字母数字字符:

输入

aa:cc:dd=foo-bar|17657V70YPQOV
ee-ff/gg=barFOO
aa_cc_dd=foo-bar|17657V70YPQOV
ee_ff_gg=barFOO
所需输出

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工具都可以使用。

假设您的输入位于名为
infle
的文件中,您可以执行以下操作:

while IFS== read key value; do
    printf '%s=%s\n' "${key//[![:alnum:]]/_}" "${value}"
done < infile
这将
IFS
变量设置为
=
,并逐行将键/值对读取为
变量


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

假设您的输入位于名为
infle
的文件中,您可以执行以下操作:

while IFS== read key value; do
    printf '%s=%s\n' "${key//[![:alnum:]]/_}" "${value}"
done < infile
这将
IFS
变量设置为
=
,并逐行将键/值对读取为
变量

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

使用
awk

$ awk -F= -v OFS='=' '{gsub("[^a-zA-Z]", "_", $1)} 1' ip.txt 
aa_cc_dd=foo-bar|17657V70YPQOV
ee_ff_gg=barFOO
$ 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
输入和输出字段分隔符设置为
=
,然后
gsub(“[^a-zA-Z]”、“u”、$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
    进行就地编辑
    • 带有
      awk

      $ awk -F= -v OFS='=' '{gsub("[^a-zA-Z]", "_", $1)} 1' ip.txt 
      aa_cc_dd=foo-bar|17657V70YPQOV
      ee_ff_gg=barFOO
      
      $ 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
      
      输入和输出字段分隔符设置为
      =
      ,然后
      gsub(“[^a-zA-Z]”、“u”、$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
        进行就地编辑

        • 任何
          Posix
          兼容
          awk

          $ awk -F= -v OFS='=' '{gsub("[^a-zA-Z]", "_", $1)} 1' ip.txt 
          aa_cc_dd=foo-bar|17657V70YPQOV
          ee_ff_gg=barFOO
          
          $ 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、替换、目标)
          这与
          sub
          功能类似,只是
          gsub
          替换了 所有最长、最左侧、不重叠的匹配 它可以找到的子字符串。
          gsub
          中的
          g
          代表全局,这意味着到处替换,
          gsub
          函数返回数字 替换的数量


          +1
          每当gsub返回
          0
          Any
          Posix
          兼容
          awk

          $ awk -F= -v OFS='=' '{gsub("[^a-zA-Z]", "_", $1)} 1' ip.txt 
          aa_cc_dd=foo-bar|17657V70YPQOV
          ee_ff_gg=barFOO
          
          $ 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、替换、目标)
          这与
          sub
          功能类似,只是
          gsub
          替换了 所有最长、最左侧、不重叠的匹配 它可以找到的子字符串。
          gsub
          中的
          g
          代表全局,这意味着到处替换,
          gsub
          函数返回数字 替换的数量


          +1
          每当gsub返回
          0

          时,它会处理默认操作
          {print$0}
          ,我想我会加入一点ruby:

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

          我想我会扔一点红宝石进去:

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