问题描述
我有这样提供的 m3u 列表:
#EXTM3U
#EXTINF:0 tvg-id="Channel 1" tvg-name="Channel 1" tvg-logo="http://host/logo/logo1.png" timeshift="5" catchup="default" catchup-source="http://1.1.1.1/325/mono-{utc}-{lutc}.m3u8?token=secret" group-title="Group",13 Channel 1
http://2.2.2.2/325/video.m3u8?token=secret
#EXTINF:0 tvg-id="Channel 2" tvg-name="Channel 2" tvg-logo="http://host/logo/logo2.png" timeshift="5" catchup="default" catchup-source="http://1.1.1.1/324/mono-{utc}-{lutc}.m3u8?token=secret" group-title="Group",Channel 2
http://2.2.2.2/324/video.m3u8?token=secret
#EXTINF:0 tvg-id="Channel 3" tvg-name="Channel 3" tvg-logo="http://host/logo/logo3.png" timeshift="5" catchup="default" catchup-source="http://1.1.1.1/323/mono-{utc}-{lutc}.m3u8?token=secret" group-title="Group",Channel 3
http://2.2.2.2/323/video.m3u8?token=secret
我想将 catchup 类型更改为 fs 并删除所有 catchup-source 标记,因此结果应该是:
#EXTM3U
#EXTINF:0 tvg-id="Channel 1" tvg-name="Channel 1" tvg-logo="http://host/logo/logo1.png" timeshift="5" catchup="fs" group-title="Group",13 Channel 1
http://2.2.2.2/325/video.m3u8?token=secret
#EXTINF:0 tvg-id="Channel 2" tvg-name="Channel 2" tvg-logo="http://host/logo/logo2.png" timeshift="5" catchup="fs" group-title="Group",Channel 2
http://2.2.2.2/324/video.m3u8?token=secret
#EXTINF:0 tvg-id="Channel 3" tvg-name="Channel 3" tvg-logo="http://host/logo/logo3.png" timeshift="5" catchup="fs" group-title="Group",Channel 3
http://2.2.2.2/323/video.m3u8?token=secret
如何在 bash 中做到这一点?我用 sed 尝试过,但没有成功,你能指出我正确的方向吗?
要删除任何特定的子字符串,我可以像这样使用 sed:
sed '/text to remove/d' ./file
就我而言,要删除的字符串在 catchup="default"
和 group-title=
之间有所不同,并在我发布时得到结果。
解决方法
像这样:
shopt -s extglob ; cat file.txt | while read -r line ; do mapfile -t -d ' ' Line < <(printf '%s' "${line}" | cut -f 1-99 -d ' ') ; for field in "${Line[@]}"; do if [[ "$field" =~ catchup-source=.* ]]; then : ; elif [[ "$field" == catchup=\"default\" ]]; then printf '%s ' 'catchup="fs"'; else [[ -n "$field" ]] && { if [[ "$field" =~ .*$'\n'.* ]]; then printf '%s' "$field" ; else printf '%s ' "$field" ; fi } ; fi; done ; done
说明:
逐行读取文件,将其拆分为以空格为分隔符的字段,并将它们存储在数组中。对数组中的每个字段检查内容:如果内容是catchup默认的东西,把它改成catchup=fs东西,如果内容是catchup-source,就继续(':'表示真),否则检查该字段是否有内容(-n),如果有内容,检查该字段的内容是否有换行符,是否只打印内容,否则打印带有分隔符的空格的内容。
,你已经完成了一半。
sed -i.bak -E -e 's/catchup="default" /catchup="fs" /g;s/catchup-source=[^ ]+ //g' file
对部分字符串 s/MATCH/REPLACEMENT/
使用搜索和替换是您所需要的(而不是删除匹配的行 /MATCH/d
)。
因此,我们搜索 catchup="default"
的每一个字面出现,并用空 //g
替换它(g
技术上没有必要,因为应该只有一次出现 catchup=
) s/catchup="default" //g
然后对 catchup-source=[^ ]+
执行相同操作(catchup-source=
后跟不是空格的任何内容,后跟空格 [^ ]+
。完成。
我们将此作为文件内替换 -i
并告诉它创建备份版本 -i.bak
。