从 m3u 文件中删除标签
Remove tags from m3u file
我有这样提供的 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
说明:
逐行读取文件,将其拆分为以space作为分隔符的字段并将其存储在数组中。对于数组中的每个字段检查内容:如果内容是 catchup default thing,将其更改为 catchup=fs thing,如果内容是 catchup-source,则继续(':' 表示 true),否则检查字段是否有内容(-n),如果它有内容,检查该字段的内容是否有换行符,如果它只打印内容,否则打印带有分隔符 space 的内容。
你已经完成了一半。
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
在技术上不是必需的,因为 [=16 应该只出现一次=]) s/catchup="default" //g
然后对 catchup-source=[^ ]+
执行相同的操作(catchup-source=
后跟任何不是 space 的内容,然后是 space [^ ]+
。完成。
我们将此作为文件内替换 -i
并告诉它创建备份版本 -i.bak
。
我有这样提供的 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
说明:
逐行读取文件,将其拆分为以space作为分隔符的字段并将其存储在数组中。对于数组中的每个字段检查内容:如果内容是 catchup default thing,将其更改为 catchup=fs thing,如果内容是 catchup-source,则继续(':' 表示 true),否则检查字段是否有内容(-n),如果它有内容,检查该字段的内容是否有换行符,如果它只打印内容,否则打印带有分隔符 space 的内容。
你已经完成了一半。
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
在技术上不是必需的,因为 [=16 应该只出现一次=]) s/catchup="default" //g
然后对 catchup-source=[^ ]+
执行相同的操作(catchup-source=
后跟任何不是 space 的内容,然后是 space [^ ]+
。完成。
我们将此作为文件内替换 -i
并告诉它创建备份版本 -i.bak
。