-1

I have a script that fetches weather api then should output the data into a file, my problem is that in the last loop it outputs the results into a file that has the variable value instead of the name. Is there a way to use the variable name instead?

#city
tromso="lat=69.6492&lon=18.9553"
gjovik="lat=60.8941&lon=10.5001"
oslo="lat=59.9139&lon=10.7522"
trondheim="lat=63.4305&lon=10.39.51"
bergen="lat=60.3913&lon=5.3221"
echo "a"

#Creates a directory
#mkdir scraped-weather

#Loops through the cities and puts the name in
for CITY  in tromso gjovik oslo trondheim bergen; do
         echo ${CITY} > ${CITY}.txt
done
echo "b"


#I get the data for each city and puts it in the city file
for CITY in $tromso $gjovik $oslo $trondheim $bergen; do
         curl -s "$API$CITY"  |  grep -A5 -E '[0-9]{2}-[0-9]{2}-[0-9]{2}'  >> ${CITY}.txt 
done
Arawelo
  • 33
  • 6
  • 2
    You can use `${!CITY}` to resolve the value so change last loop to use same list as first loop (i.e. `for CITY in tromso gjovik oslo trondheim bergen; do` ) and change to `curl -s "$API${!CITY}" .... >> ${CITY}.txt`. ( This was in this [answer](https://stackoverflow.com/a/74434549/17856705) to a Q you asked a few days ago. - see "Alternative" section.) – Computable Nov 17 '22 at 10:22
  • Hi @Gardener that unfortunately doesn't help since the script then outputs the value of the variable as a name for the file. F.ex 'lat=69.6492&lon=18.9553'.txt. – Arawelo Nov 17 '22 at 10:48
  • 1
    From your description, I absolutely don't know what you want to achieve. Which file should the output of the `grep` be appended to? BTW, wouldn't it be easier to make `CITY` an associative array, the keys being the city names and the values the city coordinates? – user1934428 Nov 17 '22 at 13:14
  • Why is this tagged with _terminal_, when you just want to discuss a _bash program_? There is nothing terminal-specific in your question. – user1934428 Nov 17 '22 at 13:16
  • You loop on the values of each city, instead of the names of the cities, like in your first loop. So when you redirect the output to `${CITY}`, you are sending the output to the lat long values. Your last loop `for` should be the same as the first one. – Nic3500 Nov 18 '22 at 01:13
  • Are you able to share the string value for ${API} ? – Eric Marceau Nov 27 '22 at 20:22

2 Answers2

0

I located a URL I could use as substitute for your ${API} and came up with the following adaptation of your script.

The logic does NOT use your variable values assigned to each city ... because these were not required for this version of the script (obviously URL dependent).

I also coded a few extra lines to get additional info from that site.

Finally, I added a loop to build a simplistic HTML page for local viewing the compiled extracts.

#!/bin/sh

#QUESTION:  https://stackoverflow.com/questions/74472892/how-to-use-the-variable-name-as-file-name-instead-of-value

CITY_LIST="Ottawa Montreal Toronto Quebec Halifax Calgary Victoria"
CITY_LIST="Tromso Gjovik Oslo Trondheim Bergen"

### Generic Weather Site
#https://www.meteoprog.com/weather/Tromso/
API="https://www.meteoprog.com/weather/"

#Creates a directory
#mkdir scraped-weather

#Loops through the cities
for CITY in $(echo ${CITY_LIST})
do
    echo "\n Pulling report for ${CITY} ..."

    rm -f "${CITY}.txt"
    ### Place city name at start of file
    #echo "${CITY}" > "${CITY}.txt"

    ### I get the data for each city and puts it in the city file
    #curl -s "${API}${CITY}/"  |  grep -A5 -E '[0-9]{2}-[0-9]{2}-[0-9]{2}'  >> ${CITY}.txt 
    curl -s "${API}${CITY}/" > "${CITY}_RAW.txt"

    ### Extract directly relevant segments
    tail -n +2 "${CITY}_RAW.txt"  |
    grep -A5 -E '[0-9]{2}-[0-9]{2}-[0-9]{2}' >> "${CITY}.txt"

    tail -n +2 "${CITY}_RAW.txt"  |
    grep -A3 'class="feels-like"' >> "${CITY}.txt"

    tail -n +2 "${CITY}_RAW.txt"  |
    grep -A27 'class="today__atmosphere"' >> "${CITY}.txt"

    #rm -f "${CITY}_RAW.txt"
done

### Build-up HTML page for viewing locally
{
    echo "<HTML><BODY>"
    for CITY in $(echo ${CITY_LIST})
    do
        cat "${CITY}.txt"
    done
    echo "</BODY></HTML>"
} >WEATHER_REPORT.html

The HTML page is as follows:

<HTML><BODY>
        <h2>Currently in Tromso <time datetime="2022-11-27T22:25:20+01:00"><span class="city-local-time">22:25</span> - 27 November, Sunday</time></h2>
        <div class="current-temperature">
            <div class="today-temperature">
                <span dir="ltr">-3°</span>
                <div class="icons icons81x73 night moon-cloud_2" title="cloudy, clear at times, no precipitation"></div>
            </div>
        <span class="feels-like">
            Feels Like <b>-5°C</b>                        <div class="cool">Cool</div>
        </span>

        <table class="today__atmosphere">
            <tbody>
                            <tr>
                    <th>Chance of precipitation</th>
                    <td class="atmosphere-spec"><span class="icon-rain-drops"></span><b>0</b> %</td>
                </tr>
                        <tr>
                <th>Wind</th>
                                <td class="atmosphere-spec"><span class="icon-wind"></span><b>3</b> mps</td>
            </tr>
            <tr>
                <th>Pressure</th>
                <td class="atmosphere-spec"><span class="icon-meater"></span><b>753</b> </td>
            </tr>
            <tr>
                <th>UV Index</th>
                <td class="atmosphere-spec"><span class="icon-uv"></span><b>0/12</b></td>
            </tr>
            <tr>
                <th>Humidity</th>
                <td class="atmosphere-spec"><span class="icon-dropp"></span><b>83</b> %</td>
            </tr>
            <tr>
                <th>Precipitation</th>
                <td class="atmosphere-spec"><span class="icon-rainfall"></span><b>0</b> mm</td>
            </tr>
            </tbody>
        </table>
        <h2>Currently in Gjovik <time datetime="2022-11-27T22:28:08+01:00"><span class="city-local-time">22:28</span> - 27 November, Sunday</time></h2>
        <div class="current-temperature">
            <div class="today-temperature">
                <span dir="ltr">+2°</span>
                <div class="icons icons81x73 night cloud_2-rain" title="overcast, light rain"></div>
            </div>
        <span class="feels-like">
            Feels Like <b>+2°C</b>                        <div class="cool">Cool</div>
        </span>

        <table class="today__atmosphere">
            <tbody>
                            <tr>
                    <th>Chance of precipitation</th>
                    <td class="atmosphere-spec"><span class="icon-rain-drops"></span><b>60</b> %</td>
                </tr>
                        <tr>
                <th>Wind</th>
                                <td class="atmosphere-spec"><span class="icon-wind"></span><b>2</b> mps</td>
            </tr>
            <tr>
                <th>Pressure</th>
                <td class="atmosphere-spec"><span class="icon-meater"></span><b>751</b> </td>
            </tr>
            <tr>
                <th>UV Index</th>
                <td class="atmosphere-spec"><span class="icon-uv"></span><b>0/12</b></td>
            </tr>
            <tr>
                <th>Humidity</th>
                <td class="atmosphere-spec"><span class="icon-dropp"></span><b>98</b> %</td>
            </tr>
            <tr>
                <th>Precipitation</th>
                <td class="atmosphere-spec"><span class="icon-rainfall"></span><b>0.4</b> mm</td>
            </tr>
            </tbody>
        </table>
        <h2>Currently in Oslo <time datetime="2022-11-27T22:28:10+01:00"><span class="city-local-time">22:28</span> - 27 November, Sunday</time></h2>
        <div class="current-temperature">
            <div class="today-temperature">
                <span dir="ltr">+4°</span>
                <div class="icons icons81x73 night cloud_2" title="overcast, no significant precipitation"></div>
            </div>
        <span class="feels-like">
            Feels Like <b>+4°C</b>                        <div class="cool">Cool</div>
        </span>

        <table class="today__atmosphere">
            <tbody>
                            <tr>
                    <th>Chance of precipitation</th>
                    <td class="atmosphere-spec"><span class="icon-rain-drops"></span><b>40</b> %</td>
                </tr>
                        <tr>
                <th>Wind</th>
                                <td class="atmosphere-spec"><span class="icon-wind"></span><b>2</b> mps</td>
            </tr>
            <tr>
                <th>Pressure</th>
                <td class="atmosphere-spec"><span class="icon-meater"></span><b>757</b> </td>
            </tr>
            <tr>
                <th>UV Index</th>
                <td class="atmosphere-spec"><span class="icon-uv"></span><b>0/12</b></td>
            </tr>
            <tr>
                <th>Humidity</th>
                <td class="atmosphere-spec"><span class="icon-dropp"></span><b>96</b> %</td>
            </tr>
            <tr>
                <th>Precipitation</th>
                <td class="atmosphere-spec"><span class="icon-rainfall"></span><b>0.07</b> mm</td>
            </tr>
            </tbody>
        </table>
        <h2>Currently in Trondheim <time datetime="2022-11-27T22:28:11+01:00"><span class="city-local-time">22:28</span> - 27 November, Sunday</time></h2>
        <div class="current-temperature">
            <div class="today-temperature">
                <span dir="ltr">+4°</span>
                <div class="icons icons81x73 night cloud_2-rain" title="overcast, light rain"></div>
            </div>
        <span class="feels-like">
            Feels Like <b>+3°C</b>                        <div class="cool">Cool</div>
        </span>

        <table class="today__atmosphere">
            <tbody>
                            <tr>
                    <th>Chance of precipitation</th>
                    <td class="atmosphere-spec"><span class="icon-rain-drops"></span><b>30</b> %</td>
                </tr>
                        <tr>
                <th>Wind</th>
                                <td class="atmosphere-spec"><span class="icon-wind"></span><b>3</b> mps</td>
            </tr>
            <tr>
                <th>Pressure</th>
                <td class="atmosphere-spec"><span class="icon-meater"></span><b>756</b> </td>
            </tr>
            <tr>
                <th>UV Index</th>
                <td class="atmosphere-spec"><span class="icon-uv"></span><b>0/12</b></td>
            </tr>
            <tr>
                <th>Humidity</th>
                <td class="atmosphere-spec"><span class="icon-dropp"></span><b>80</b> %</td>
            </tr>
            <tr>
                <th>Precipitation</th>
                <td class="atmosphere-spec"><span class="icon-rainfall"></span><b>0.19</b> mm</td>
            </tr>
            </tbody>
        </table>
        <h2>Currently in Bergen <time datetime="2022-11-27T22:28:12+01:00"><span class="city-local-time">22:28</span> - 27 November, Sunday</time></h2>
        <div class="current-temperature">
            <div class="today-temperature">
                <span dir="ltr">+5°</span>
                <div class="icons icons81x73 night cloud_2" title="overcast, no significant precipitation"></div>
            </div>
        <span class="feels-like">
            Feels Like <b>+3°C</b>                        <div class="cool">Cool</div>
        </span>

        <table class="today__atmosphere">
            <tbody>
                            <tr>
                    <th>Chance of precipitation</th>
                    <td class="atmosphere-spec"><span class="icon-rain-drops"></span><b>90</b> %</td>
                </tr>
                        <tr>
                <th>Wind</th>
                                <td class="atmosphere-spec"><span class="icon-wind"></span><b>5</b> mps</td>
            </tr>
            <tr>
                <th>Pressure</th>
                <td class="atmosphere-spec"><span class="icon-meater"></span><b>752</b> </td>
            </tr>
            <tr>
                <th>UV Index</th>
                <td class="atmosphere-spec"><span class="icon-uv"></span><b>0/12</b></td>
            </tr>
            <tr>
                <th>Humidity</th>
                <td class="atmosphere-spec"><span class="icon-dropp"></span><b>91</b> %</td>
            </tr>
            <tr>
                <th>Precipitation</th>
                <td class="atmosphere-spec"><span class="icon-rainfall"></span><b>0.09</b> mm</td>
            </tr>
            </tbody>
        </table>
</BODY></HTML>
Eric Marceau
  • 1,601
  • 1
  • 8
  • 11
  • If you actually have bash (not some more basic shell like dash), arrays are a much better way to store lists than space-delimited strings. Also, `$(echo something)` is almost never a good idea, since the `$( )` and `echo` basically cancel each other out (except for some potentially weird parsing in between); just use the string directly. – Gordon Davisson Nov 27 '22 at 22:43
  • I use #!/bin/sh (sh/dash) wherever I can and only go to bash when forced to do so. I try to stick to the most common minimal-set shell for portability and forward compatibility. – Eric Marceau Nov 27 '22 at 23:04
0

As user1934428 suggested in a comment, an associative array would be a better way to do this. Using city names as variable names will get you into trouble with any cities with non-variable-compatible characters (e.g. Mo i Rana). You'd define the array something like this:

declare -A cities    # Note: need to explicitly declare associative arrays
cities=(
    [tromso]="lat=69.6492&lon=18.9553"
    [gjovik]="lat=60.8941&lon=10.5001"
    [oslo]="lat=59.9139&lon=10.7522"
    [trondheim]="lat=63.4305&lon=10.39.51"
    [bergen]="lat=60.3913&lon=5.3221"
    ["mo i rana"]="lat=66.3128&lon=14.1428"
)

Then, to loop over the city names, you'd use "${!cities[@]}". The ! makes it get the indexes (the city names) rather than the values the coordinates). To get the coordinates of a city, you'd use "${cities["$city_name"]}". If (as in the list here) there are any cities with non-filename-friendly names, you can sanitize them before using them for filenames.

for city_name in "${!cities[@]}"; do
    filename="${city_name// /-}.txt"    # Convert spaces to dashes
    echo "$city_name" >"$filename"
    curl -s "$API${cities["$city_name"]}" | grep -A5 -E '[0-9]{2}-[0-9]{2}-[0-9]{2}' >> "$filename"
done

Some other general scripting hygene recommendations: put double-quotes around all variable references (e.g. "$city_name" instead of just $city_name) to prevent weird parsing problems. Also, there are a bunch of all-caps variable names with special meanings, so to avoid conflicts it's safest to use lower- or mixed-case names for your own variables. Running your scripts through shellcheck.net is a good way to spot common mistakes before they become problems.

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151