使用Bash的Sed工具基于频道名称匹配替换频道列表文件中的服务引用
使用Bash的Sed工具基于频道名称匹配替换频道列表文件中的服务引用
我来帮你解决这个问题——核心思路是先从全局源文件建立「频道名-新服务引用」的映射,再用这个映射批量替换频道列表里的旧服务引用。直接用sed跨文件匹配不太方便,我们可以结合awk生成sed规则脚本,再一次性执行替换,高效又可靠。
实现步骤和代码
假设你的全局源文件叫global_sources.txt,频道列表文件叫channellist.txt,直接运行以下脚本即可完成原地替换:
# 第一步:生成sed替换规则脚本,处理正则特殊字符和格式细节 awk '{ # 从全局源文件中提取频道名(最后一个字段)和新服务引用(第三个字段) channel_name = $NF; new_sref = $3; # 转义频道名里的正则特殊字符(比如.、*这类),避免干扰sed匹配 gsub(/[.*+?^$(){}|[\]\\]/, "\\\\&", channel_name); # 生成精确的替换规则:匹配旧服务引用,替换为新的,保留原行的频道名和描述部分 printf "s/#SERVICE 1:0:1:0:0:0:0:0:0:0::(.*#DESCRIPTION %s)\"/#SERVICE %s::\\1\"/\n", channel_name, new_sref; }' global_sources.txt > replace_rules.sed # 第二步:应用规则到频道列表文件,原地修改 # 兼容GNU sed(Linux)和BSD sed(macOS)的写法 sed -i.bak -f replace_rules.sed channellist.txt # 删除自动生成的备份文件 rm channellist.txt.bak # 第三步:清理临时规则文件 rm replace_rules.sed
工作原理详解
生成替换规则:
awk遍历全局源文件的每一行,把频道名和对应的新服务引用提取出来。因为频道名可能包含正则特殊字符(比如空格、.),所以先转义这些字符,避免sed匹配出错。然后生成对应的sed替换命令,确保只替换对应频道名的旧服务引用。执行替换:
用sed -f加载生成的规则脚本,-i.bak实现原地修改同时生成备份文件(兼容不同系统的sed版本),最后删除备份和临时规则文件即可。
针对你给出的例子验证
全局源文件里的两行:
28.2e channel4.uk 1:0:1:2085:808:2:11A0000:0:0:0: channel 4 28.2e skyhistory.uk 1:0:1:C4C0:811:2:11A0000:0:0:0: sky history
脚本会生成两个sed规则:
s/#SERVICE 1:0:1:0:0:0:0:0:0:0::(.*#DESCRIPTION channel 4)\"/#SERVICE 1:0:1:2085:808:2:11A0000:0:0:0::\1\"/ s/#SERVICE 1:0:1:0:0:0:0:0:0:0::(.*#DESCRIPTION sky history)\"/#SERVICE 1:0:1:C4C0:811:2:11A0000:0:0:0::\1\"/
执行后,频道列表里的两行旧服务引用会被精准替换成对应的新引用,完全符合你的需求。
备注:内容来源于stack exchange,提问作者ni_hao
相关产品推荐
相关产品推荐

