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

时间:2017-02-20 00:44:15

标签: regex awk sed tr

我正在尝试用=替换_的第一部分(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

我尝试了以下模式:Using npm: $ npm install --save history Then with a module bundler like webpack, use as you would anything else: // using ES6 modules import createHistory from 'history/createBrowserHistory' // using CommonJS modules var createHistory = require('history').createBrowserHistory 但没有取得多大成功。可以使用任何基本的GNU / Linux工具。

4 个答案:

答案 0 :(得分:2)

使用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进行内部编辑

答案 1 :(得分:1)

假设您的输入位于名为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变量设置为=,并逐行将您的键/值对读入keyvalue变量。

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

答案 2 :(得分:1)

符合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替换除外        所有最长,最左边,非重叠匹配        它可以找到的子串。 g中的gsub代表全局,这意味着替换所有地方,gsub函数返回数字   取代了

+1只要gsub返回{print $0}

,它就会处理默认操作0

答案 3 :(得分:0)

以为我会抛出一点点红宝石:

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