Search code examples
bashawksedm3u

Delete multiple lines from an M3U file that does not match pattern


I have an m3u file and I want to delete some lines from it. I know which channels I would like to keep from the m3u file. This list is of channels I want to keep is shorter than the list of channels I don't want.

Input file

#EXTM3U
#EXTINF:-1,ex-Yu: TV 1
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3168.ts
#EXTINF:-1,ex-Yu: TK Tuzla
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3164.ts
#EXTINF:-1,ex-Yu: SOS
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3191.ts
#EXTINF:-1,NL: NPO 1
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3190.ts
#EXTINF:-1,NL: NPO 2
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3167.ts
#EXTINF:-1,GB: Discovery
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3166.ts
#EXTINF:-1,GB: NGC
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3201.ts
#EXTINF:-1,NL: NPO 3
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3200.ts
#EXTINF:-1,IT: SKY Sport
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3198.ts
#EXTINF:-1,ex-Yu: Pink Film
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3199.ts
#EXTINF:-1,GB: Sky Sport
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3172.ts
#EXTINF:-1,ex-Yu: N1 Bosna
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3197.ts
#EXTINF:-1,DE: Bundesliga
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3195.ts
#EXTINF:-1,ex-Yu: MTV
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3170.ts
#EXTINF:-1,ex-Yu: Mini TV
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3177.ts
#EXTINF:-1,ex-Yu: M1 Film
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3179.ts
#EXTINF:-1,ex-Yu: Lov I Ribolov
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3196.ts
#EXTINF:-1,ex-Yu: Klasik TV
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3194.ts

Above is a shortened list of all channels. I know I would like to keep the following channels:

  • All channels starting with NL: (case sensitive)
  • All channels with sky sport in it (not case sensitive)
  • All channels with DE: Bundesliga in it

Wanted result

#EXTM3U
#EXTINF:-1,NL: NPO 1
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3190.ts
#EXTINF:-1,NL: NPO 2
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3167.ts
#EXTINF:-1,NL: NPO 3
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3200.ts
#EXTINF:-1,IT: SKY Sport
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3198.ts
#EXTINF:-1,GB: Sky Sport
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3172.ts
#EXTINF:-1,DE: Bundesliga
http://channel.domain.com:9603/live/YHJKUYII/02490j4/3195.ts

I can't get this to work in either sed, awk or any other bash tool which can do the job. Any ideas?


Solution

  • You can use the following command:

    sed -n -r -e '/EXTM3U/p' -e '/NL:|DE: Bundesliga/,+1p' -e '/sky sport/I,+1p'
    

    For each matching pattern, it prints the current line and the following line.

    -n suppresses automatic printing of pattern, -r uses extended regular expressions, and -e allows to add multiple sed scripts on the same command.

    /EXTM3U/p is the simplest: it matches lines containing EXTM3U and prints them (p)

    For '/NL:|DE: Bundesliga/,+1p', it matches lines containing NL: or DE: Bundesliga, and prints it (p) as well as the following line (+1)

    For /sky sport/I, I makes a case insensitive match.