I have m3u list provided like this:
#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
I want to change catchup type to fs and remove all catchup-source tags, so result should be:
#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
How to do that in bash? I tried with sed, but without success, can you point me right direction?
To remove any specific substring, I can use sed like this:
sed '/text to remove/d' ./file
In my case, string to remove is vary, between catchup="default"
and group-title=
and get result as I posted.
Like this:
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
Explanation:
Read the file line by line, split it into fields with space as delimiter and store those in an array. For each field in the array check the contents: if the content is catchup default thing, change it to catchup=fs thing, if content is catchup-source, just continue (':' meaning true), else check if the field has content (-n), and if it has content, check if the content of the field has a newline and if it does just print the content, else print the content with the space which was the delimiter.
You were halfway there.
sed -i.bak -E -e 's/catchup="default" /catchup="fs" /g;s/catchup-source=[^ ]+ //g' file
Using search and replace for partial strings s/MATCH/REPLACEMENT/
is what you needed (rather than deleting the matching line /MATCH/d
).
So we search for every literal occurrence of catchup="default"
and replace it with nothing //g
(the g
is technically not necessary as there should be only one occurrence of catchup=
) s/catchup="default" //g
and then do the same for catchup-source=[^ ]+
( catchup-source=
followed by anything that's not a space followed by a space [^ ]+
. Done.
We do this as an infile-replacement -i
and tell it to create a backup-version -i.bak
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.