【发布时间】:2018-11-17 22:02:21
【问题描述】:
我正在寻找一种从文件中删除特殊字符的选项,但以下 3 项除外,.@
以下 awk 命令关闭,但它删除了所有标点符号。
awk '{gsub(/[[:punct:]]/,"",except(".","@",","))}1' test.csv > test2.csv
任何想法...
【问题讨论】:
我正在寻找一种从文件中删除特殊字符的选项,但以下 3 项除外,.@
以下 awk 命令关闭,但它删除了所有标点符号。
awk '{gsub(/[[:punct:]]/,"",except(".","@",","))}1' test.csv > test2.csv
任何想法...
【问题讨论】:
在 POSIX 中没有相反的字符类,也没有环顾四周来限制更通用的模式,但有一些例外。唯一的方法是拼出 POSIX 字符类。
根据Character Classes and Bracket Expressions:
‘[:punct:]’
标点符号;在'C'语言环境和ASCII字符编码中,这是"#987654328%987654330&(987654333*987654335,,@,,987654336 @,@,@ @ @ 987654336 987654337.987654339:987654341<987654343>987654345@987654347\987654349^987654351\987654353 @|}~.
你可以使用
/[!-+\/:-?[-`{-~-]/
请参阅regex demo。
传奇:
【讨论】:
所有这 3 种方法都适用于任何语言环境,只需更改类名即可适用于任何字符类,并且适用于其他括号表达式或字符串等:
1) 只需查找任何 punct,但仅在它不是您不想更改的字符之一时进行更改:
$ echo 'a.b?c#d@e,f' |
awk '{
new = ""
while ( match($0,/[[:punct:]]/) ) {
chr = substr($0,RSTART,1)
new = new substr($0,1,RSTART-1) (chr ~ /[,.@]/ ? chr : "")
$0 = substr($0,RSTART+RLENGTH)
}
print new $0
}'
a.bcd@e,f
2) 先把不想改的字符转成其他字符串,然后再转回来:
$ echo 'a.b?c#d@e,f' |
awk '{
gsub(/a/,"aA"); gsub(/,/,"aB"); gsub(/\./,"aC"); gsub(/@/,"aD")
gsub(/[[:punct:]]/,"")
gsub(/aD/,"@"); gsub(/aC/,"."); gsub(/aB/,","); gsub(/aA/,"a")
print
}'
a.bcd@e,f
将a 更改为aA 并返回以保证您在转换@ 等时创建的字符串是当时输入中其他地方不存在的字符串,这就是您可以安全地转换它们的原因之后回来。
3) 用 RS 值作为后缀,然后从您不想更改的字符中删除 RS 后缀,然后更改剩余的带有 RS 后缀的 punct:
$ echo 'a.b?c#d@e,f' |
awk '{
gsub(/[[:punct:]]/,"&"RS)
$0 = gensub("([,.@])"RS,"\\1","g")
gsub("[[:punct:]]"RS,"")
print
}'
a.bcd@e,f
那个使用 GNU awk 进行 gensub(),而其他 awk 则需要 match()+substr()。
【讨论】: