如何使用Sed删除含指定特殊字符的子域名行并保留连字符-
问题
我手头有一份子域名列表,需要删除所有包含以下特殊字符的Wildcard(通配符)子域名行:
()!&$#*+?
这些特殊字符大多随机出现在子域名前缀位置,也可能出现在字符串中部,以下是待清理数据的样例:
(www.imgur.com ***************diet.blogspot.com *-1.gbc.criteo.com ------------------------------------------------------------i.imgur.com
遍历排查列表时这类无效数据造成了诸多不便,我尝试使用sed命令处理该问题,但以下命令均未生效:
sed -i "/[!()#$&?+]/d" foo.txt ###未生效 sed -i "/[\!\(\)\#\$\&\?\+]/d" ###转义字符后仍未生效
执行上述命令后列表内容未发生任何变化,文件仍保持原始状态。我曾考虑通过串联多个sed命令逐个匹配删除对应特殊字符,测试命令如下:
cat foo.txt | sed -e "/!/d" -e "/#/d" -e "/\*/d" -e "/\$/d" -e "/(/d" -e "/)/d" -e "/+/d" -e "/\'/d" -e "/&/d" >> foo2.txt cat foo.txt | sed -e "/\!/d" | sed -e "/\#/d" | sed -e "/\*/d" | sed -e "/\$/d" | sed -e "/\+/d" | sed -e "/\'/d" | sed -e "/\&/d" >> foo2.txt
尝试转义所有特殊字符后命令仍未生效,后续添加/g参数测试也没有效果。
补充说明:我不希望删除连字符
-,因为部分合法子域名包含该字符,例如:line-apps.com line-apps-beta.com line-apps-rc.com line-apps-dev.com
解决方案
你之前的命令没生效核心是两个常见问题:
- 用双引号包裹sed匹配规则时,shell会提前解析字符串内的
$、&、!这类特殊字符,最终传给sed的匹配规则已经被篡改,和你写的逻辑完全不一致 - sed的方括号字符集有特殊语法规则,如果特殊字符摆放位置不对,很容易被识别成取反标记、范围标记,直接导致匹配逻辑失效
直接使用下面的命令即可,用单引号包裹规则完全避开shell的预解析,匹配列表不包含连字符,不会误删合法域名:
# 直接原地修改原文件 sed -i '/[()!$#*+?&]/d' foo.txt
如果需要先确认过滤效果、不改动原文件,可以去掉-i参数执行,处理结果会直接打印在终端:
sed '/[()!$#*+?&]/d' foo.txt
不需要额外给方括号内的特殊字符加转义,sed在方括号字符集内部会默认把这些符号识别为普通文本,多余的转义反而可能触发异常匹配。
如果偏好使用grep,也可以通过反向匹配实现完全一致的过滤效果:
grep -v '[()!$#*+?&]' foo.txt > foo_clean.txt
内容的提问来源于stack exchange,提问作者user19219732
相关产品推荐
相关产品推荐

