Search code examples
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
    
    • Remove the ,p from the script to silence the output to stdout or if you're satisfied with the output.

    • Change Q to w from the script if in-place editing is needed.


    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