简体   繁体   中英

Remove tags from m3u file

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM