bashshellif-statementwhile-loopm3u

Bash script, if statement in while loop, unwanted duplicate output


I'm doing a script to parse m3u files. The goal is to retrieve the variable tag and the url. I tested with this file.

#!/bin/bash

echo "name,tvg-id,tvg-name,tvg-country,group-title,languages,url"
while IFS= read -r line; do
    tags_detect="$(echo "$line" | grep -Eo '^#EXTINF:')"

    if [[ -n ${tag_detect} ]]; then
        get_chno="$(echo "$line" | grep -o 'tvg-chno="[^"]*' | cut -d '"' -f2)"
        get_id="$(echo "$line" | grep -o 'tvg-id="[^"]*' | cut -d '"' -f2)"
        get_logo="$(echo "$line" | grep -o 'tvg-logo="[^"]*' | cut -d '"' -f2)"
        get_grp_title="$(echo "$line" | grep -o 'group-title="[^"]*' | cut -d '"' -f2)"
        get_title="$(echo "$line" | grep -o ',[^*]*' | cut -d ',' -f2)"
        get_tvg_name="$(echo "$line" | grep -o 'tvg-name="[^"]*' | cut -d '"' -f2)"
        get_country="$(echo "$line" | grep -o 'tvg-country="[^"]*' | cut -d '"' -f2)"
        get_language="$(echo "$line" | grep -o 'tvg-language="[^"]*' | cut -d '"' -f2)"

        phrase="${get_title},${get_id},${get_tvg_name},${get_country},${get_grp_title},${get_language}"
    else
        url="$line"

    fi
    echo "${phrase},${url}"

done <"${1}"

So, Without "If" it works but i don't have url. I add a "IF" and ... :

,#EXTM3U
4 Turk Music,4TurkMusic.fr,4 Turk Music,FR;TK,Music,Turkish,#EXTM3U
4 Turk Music,4TurkMusic.fr,4 Turk Music,FR;TK,Music,Turkish,http://51.210.199.30/hls/stream.m3u8
Alpe d’Huez TV,AlpedHuezTV.fr,Alpe d’Huez TV,FR,,French,http://51.210.199.30/hls/stream.m3u8
Alpe d’Huez TV,AlpedHuezTV.fr,Alpe d’Huez TV,FR,,French,https://edge10.vedge.infomaniak.com/livecast/ik:adhtv/chunklist.m3u8

... It's broken and I don't found my error.

desired output:

4 Turk Music,4TurkMusic.fr,4 Turk Music,FR;TK,Music,Turkish,http://1.2.3.4/hls/stream.m3u8
Alpe d’Huez TV,AlpedHuezTV.fr,Alpe d’Huez TV,FR,,French,https://edge10.vedge.infomaniak.com/livecast/ik:adhtv/chunklist.m3u8

I don't understand my mistake.


Solution

  • It's broken and I don't found my error.

    Paste you script at https://shellcheck.net for validation/recommendation.


    Here is how I would do it in bash.

    #!/usr/bin/env bash
    
    printf '%s\n' "name,tvg-id,tvg-name,tvg-country,group-title,languages,url"
    
    while IFS= read -r data; do
      [[ $data != '#EXTINF:-1'* ]] && continue
      IFS= read -r url && [[ $url != 'http'* ]] && echo "$url" && continue
      if [[ "$data" == '#EXTINF:-1'* && "$url" == 'http'* ]]; then
        title=${data#*\",}
        tvg_id=${data#*tvg-id=\"} tvg_id=${tvg_id%%\"*}
        tvg_name=${data#*tvg-name=\"} tvg_name=${tvg_name%%\"*}
        tvg_country=${data#*tvg-country=\"} tvg_country=${tvg_country%%\"*}
        group_title=${data#*group-title=\"} group_title=${group_title%%\",*}
        tvg_language=${data#*tvg-language=\"} tvg_language=${tvg_language%%\"*}
        printf '%s,%s,%s,%s,%s,%s,%s\n' "$title" "$tvg_id" "$tvg_name" "$tvg_country" "$group_title" "$tvg_language" "$url"
      fi
    done < file.txt
    

    Although I'm not sure what should happen at line 233 and 238 those lines starts with #EXTVLCOPT


    An ed solution if available/acceptable.

    The script, name it anything you like. I'll just name it script.ed

    g/^#EXTINF:-1/s/$/ /\
    ;/^http\(s\)\{0,1\}.*/-1;/^[^#]*$/j
    ,s/^#EXTINF:-1 tvg-id="\([^"]*\)" tvg-name="\([^"]*\)" tvg-country="\([^"]*\)" tvg-language="\([^"]*\).* group-title="\([^"]*\)",\(.*\) \(http.*\)\{0,1\}/\6,\1,\2,\3,\5,\4,\7/
    1c
    name,tvg-id,tvg-name,tvg-country,group-title,languages,url
    .
    ,p
    Q
    

    Now run it against the file in question.

    ed -s file.txt < script.ed
    

    Should give more or less same result as the bash solution, but since it is still unknown what should happen at line 233 and 238 those lines starts with #EXTVLCOPT