sed:仅删除引号内的所有非字母数字字符

Posted

技术标签:

【中文标题】sed:仅删除引号内的所有非字母数字字符【英文标题】:sed: remove all non-alphanumeric characters inside quotations only 【发布时间】:2015-03-24 12:13:00 【问题描述】:

假设我有一个这样的字符串:

Output:   
I have some-non-alphanumeric % characters remain here, I "also, have_+ some & .here"

我想删除引号内的非字母数字字符逗号、句点或空格除外

Desired Output:    
I have some-non-alphanumeric % characters remain here, I "also, have some  .here"

我尝试了以下 sed 命令匹配字符串并在引号内删除,但它会删除引号内的所有内容,包括引号:

sed '/characters/ s/\("[^"]*\)\([^a-zA-Z0-9\,\. ]\)\([^"]*"\)//g'

感谢任何帮助,最好使用sed,以获得所需的输出。提前致谢!

【问题讨论】:

sed 不是解决此问题的正确工具。 Perl 呢?你想要 perl 解决方案吗? 好吧,我将这段代码添加到现有脚本中,我将传递给其他用户... #!/bin/bash 是我的 shell,所以我认为 perl 不是在这里受益。 【参考方案1】:

您需要多次重复替换以删除所有非字母数字字符。在 sed 中执行这样的循环需要一个标签并使用 bt 命令:

sed '
# If the line contains /characters/, just to label repremove
/characters/ b repremove
# else, jump to end of script
b
# labels are introduced with colons
:repremove
# This s command says: find a quote mark and some stuff we do not want
# to remove, then some stuff we do want to remove, then the rest until
# a quote mark again. Replace it with the two things we did not want to
# remove
s/\("[a-zA-Z0-9,. ]*\)[^"a-zA-Z0-9,. ][^"a-zA-Z0-9,. ]*\([^"]*"\)/\1\2/
# The t command repeats the loop until we have gotten everything
t repremove
'

(即使没有[^"a-zA-Z0-9,. ]*,这也可以工作,但在一行包含许多非字母数字字符的行上会变慢)

虽然另一个答案是正确的,但在 perl 中执行此操作要容易得多。

【讨论】:

【参考方案2】:

Sed 不是用于此目的的正确工具。这是通过 Perl 实现的。

perl -pe 's/[^a-zA-Z0-9,.\s"](?!(?:"[^"]*"|[^"])*$)//g' file

示例:

$ echo 'I have some-non-alphanumeric % characters remain here, I "also, have_+ some & .here"' | perl -pe 's/[^a-zA-Z0-9,.\s"](?!(?:"[^"]*"|[^"])*$)//g'
I have some-non-alphanumeric % characters remain here, I "also, have some  .here"

Regex Demo

【讨论】:

以上是关于sed:仅删除引号内的所有非字母数字字符的主要内容,如果未能解决你的问题,请参考以下文章

从 lua 字符串中删除所有非字母数字字符

PHP 正则表达式 - 删除所有非字母数字字符

Shell常用正则表达式

sed:从文件中删除字母数字单词

删除批处理变量中的非字母数字字符

从字符串中删除非字母数字字符(包括 ß、Ê 等)