You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用sed仅删除完全匹配单词,排除含连字符的匹配项

解决DNS区域文件误删记录的问题

原sed命令误删带连字符的主机标签行,是因为\bsmtp\b会匹配行内任意位置的smtp(连字符属于非单词字符,会被当成单词边界)。要精确删除主机标签完全等于目标词的指定类型记录,可用以下两种方案:

方案1:改进sed命令

通过正则限定目标词必须是行首的完整第一列,再匹配记录类型:

  • 删除A记录:
    sed -ie "/^${target}\b.*\bA\b/d" "$zonefile"
    
  • 删除CNAME记录:
    sed -ie "/^${target}\b.*\bCNAME\b/d" "$zonefile"
    

关键解释:

  • ^${target}\b:确保目标词是行首的完整第一列(后面跟空格/制表符等分隔符),不会匹配test-smtp(行首是test-)或smtp5(smtp后是数字,不是单词边界)。
  • \bA\b:匹配完整的记录类型,避免误匹配含A的其他字段。

方案2:awk按列精确匹配(推荐)

awk按列处理结构化文本,完全避免正则边界问题,更可靠:

  • 删除A记录:
    awk -v tgt="$target" '{if ($1 == tgt && $4 == "A") next} 1' "$zonefile" > temp && mv temp "$zonefile"
    
  • 删除CNAME记录:
    awk -v tgt="$target" '{if ($1 == tgt && $4 == "CNAME") next} 1' "$zonefile" > temp && mv temp "$zonefile"
    

关键解释:

  • $1 == tgt:精确匹配第一列(主机标签)等于目标词,彻底杜绝部分匹配。
  • $4 == "A":对应标准DNS区域文件的记录类型列(前3列是主机标签、TTL、类IN),如果你的文件省略TTL,改成$3即可。
  • {next} 1:跳过匹配行,其他行正常输出,最后覆盖原文件。

脚本整合示例

把逻辑整合到你的my_script中:

#!/bin/bash

if [ $# -ne 3 ]; then
    echo "用法: $0 [-a|-c] <目标主机标签> <区域文件>"
    exit 1
fi

case "$1" in
    -a) RECORD_TYPE="A" ;;
    -c) RECORD_TYPE="CNAME" ;;
    *) echo "无效参数,使用 -a 或 -c"; exit 1 ;;
esac

TARGET="$2"
ZONE_FILE="$3"

# 使用awk方案(推荐)
awk -v tgt="$TARGET" -v type="$RECORD_TYPE" '{if ($1 == tgt && $4 == type) next} 1' "$ZONE_FILE" > temp.$$ && mv temp.$$ "$ZONE_FILE"

执行./my_script -a smtp sampledomainzone.com就只会删除主机标签为smtp的A记录,不会误删test-smtp、smtp-dev等行。

内容的提问来源于stack exchange,提问作者humbleStrength

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 16:57:43