Say we’re down about the lack of sunshine in our city and we really want to know what the sunniest cities in the world are. The data we’re looking at is the Wikipedia article titled List of cities by sunshine duration.
The general process we follow is 1.) extract the data, 2.) apply various transformations until it’s in the format we want it to be in, then 3.) load into whatever application we want for convenient viewing. As you can imagine, there are many ways to carry out this process, but we’re piping together command line utilities here.
The first step to extracting the text we need is the curl
command.
$ curl https://en.wikipedia.org/wiki/List_of_cities_by_sunshine_duration
HTML parsing can be very challenging, so to help narrow down the text we’re most interested in we use the pup utility. Referencing the documentation for this tool we can use the various selectors available to us and grab the text out of the table. The last column in the table is a footnote that we want to leave out.
$ pup '.wikitable:first-of-type td:not(:nth-of-type(16)) text{}'
We now have the text we want, but it’s not quite there yet, pup leaves lots of blank lines in, so to strip those out we use:
$ grep -v '^$'
Next we use awk is an incredibly useful command line tool that is frequently used in Linux systems to pull information out of semi-structured text. awk
is well suited to joining each group of 15 lines with commas and a new line at the end to bring back the table cells together to form a CSV.
putting it all together you get:
first try:
curl https://en.wikipedia.org/wiki/List_of_cities_by_sunshine_duration |
pup '.wikitable:first-of-type td:not(:nth-of-type(16)) text{}' |
grep -v '^$' |
awk '{printf "%s%s", (NR%15 == 1 ? "" : ", "), $0} NR % 15 == 0 {print ""}'
second try:
curl https://en.wikipedia.org/wiki/List_of_cities_by_sunshine_duration |
pup '.wikitable:nth-of-type(4) tr > :not(:last-child) text{}' |
grep -v '^$' |
awk '{printf "%s%s", (NR%15 == 1 ? "" : ", "), $0} NR % 15 == 0 {print ""}'
one row of weird data in North America is messing this up: “Saint Pierre and Miquelon Saint-Pierre” so we need a little refinement to our awk script. Luckily, LLMs are well versed in awk. Here’s the final version of the awk script:
final commands here:
curl https://en.wikipedia.org/wiki/List_of_cities_by_sunshine_duration |
pup '.wikitable:nth-of-type(4) tr > :not(:last-child) text{}' |
grep -v '^$' |
awk -f row-text-to-csv.awk > test.csv
Wow! that turned into more work than I expected. Surely there’s an easier way to do this! Next time. Here’s the data:
Country City | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | Year |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Canada Calgary | 119.5 | 144.6 | 177.2 | 220.2 | 249.4 | 269.9 | 314.1 | 284.0 | 207.0 | 175.4 | 121.1 | 114.0 | 2396.3 |
Canada Churchill | 79.7 | 117.7 | 177.8 | 198.2 | 197.0 | 243.0 | 281.7 | 225.9 | 112.0 | 58.1 | 55.3 | 53.1 | 1799.5 |
Canada Edmonton | 100.8 | 121.7 | 176.3 | 244.2 | 279.9 | 285.9 | 307.5 | 282.3 | 192.7 | 170.8 | 98.4 | 84.5 | 2344.8 |
Canada Iqaluit | 32.4 | 94.0 | 172.2 | 216.5 | 180.5 | 200.2 | 236.8 | 156.8 | 87.9 | 51.4 | 35.6 | 12.6 | 1476.8 |
Canada Montreal | 101.0 | 128.0 | 164.0 | 178.0 | 229.0 | 240.0 | 272.0 | 246.0 | 182.0 | 144.0 | 84.0 | 84.0 | 2051.0 |
Canada Prince Rupert | 40.1 | 65.2 | 103.0 | 145.8 | 171.1 | 154.5 | 149.7 | 149.7 | 115.7 | 72.4 | 43.0 | 32.1 | 1242.1 |
Canada Toronto | 85.9 | 111.3 | 161.0 | 180.0 | 227.7 | 259.6 | 279.6 | 245.6 | 194.4 | 154.3 | 88.9 | 78.1 | 2066.4 |
Canada Vancouver | 60.1 | 91.0 | 134.8 | 185.0 | 222.5 | 226.9 | 289.8 | 277.1 | 212.8 | 120.7 | 60.4 | 56.5 | 1937.6 |
Canada Whitehorse | 43.8 | 105.5 | 163.2 | 238.5 | 251.1 | 266.7 | 247.6 | 226.5 | 132.7 | 84.9 | 39.8 | 26.8 | 1827.1 |
Canada Winnipeg | 114.7 | 133.9 | 181.9 | 241.4 | 285.3 | 276.3 | 308.3 | 281.4 | 189.0 | 147.4 | 93.9 | 99.5 | 2352.9 |
Honduras La Ceiba | 170.5 | 192.1 | 217.0 | 234.0 | 213.9 | 192.0 | 201.5 | 217.0 | 174.0 | 151.9 | 144.0 | 151.9 | 2259.8 |
Mexico La Paz | 200 | 234 | 271 | 292 | 332 | 322 | 287 | 258 | 257 | 272 | 233 | 190 | 3148 |
Mexico Mexico City | 240 | 234 | 268 | 232 | 225 | 183 | 176 | 176 | 157 | 194 | 232 | 236 | 2555 |
Mexico Monterrey | 142 | 154 | 195 | 193 | 192 | 206 | 249 | 242 | 200 | 170 | 163 | 133 | 2239 |
Mexico Villahermosa | 168 | 185 | 252 | 215 | 278 | 217 | 252 | 245 | 167 | 150 | 170 | 144 | 2443 |
Nicaragua Managua | 263.5 | 254.2 | 291.4 | 276.0 | 229.4 | 186.0 | 151.9 | 195.3 | 210.0 | 223.2 | 231.0 | 248.0 | 2759.9 |
Panama Panama City | 228.9 | 245.2 | 183.9 | 173.1 | 108.5 | 116.3 | 106.1 | 118.1 | 99.2 | 103.9 | 139.8 | 120.5 | 1743.5 |
Puerto Rico San Juan | 237.4 | 231.2 | 282.0 | 268.3 | 255.2 | 259.4 | 280.8 | 267.8 | 234.7 | 227.2 | 202.4 | 217.4 | 2963.8 |
El Salvador San Salvador | 301 | 277 | 294 | 243 | 220 | 174 | 239 | 257 | 180 | 211 | 267 | 294 | 2957 |
Saint Pierre and Miquelon Saint-Pierre | 49.6 | 70.2 | 115.5 | 131.9 | 165.8 | 172.6 | 164.8 | 173.5 | 156.1 | 119.0 | 63.0 | 45.4 | 1427.3 |
United States Albuquerque | 234.2 | 225.3 | 270.2 | 304.6 | 347.4 | 359.3 | 335.0 | 314.2 | 286.7 | 281.4 | 233.8 | 223.3 | 3415.4 |
United States Anchorage | 82.9 | 120.5 | 195.8 | 235.3 | 288.7 | 274.7 | 250.1 | 203.9 | 159.8 | 117.1 | 80.6 | 51.8 | 2061.2 |
United States Atlanta | 164.0 | 171.7 | 220.5 | 261.2 | 288.6 | 284.8 | 273.8 | 258.6 | 227.5 | 238.5 | 185.1 | 164.0 | 2738.3 |
United States Austin | 163.8 | 169.3 | 205.9 | 205.8 | 227.1 | 285.5 | 317.2 | 297.9 | 233.8 | 215.6 | 168.3 | 153.5 | 2643.7 |
United States Baltimore | 155.4 | 164.0 | 215.0 | 230.7 | 254.5 | 277.3 | 290.1 | 264.4 | 221.8 | 205.5 | 158.5 | 144.5 | 2581.7 |
United States Boise | 109.3 | 151.9 | 238.6 | 281.4 | 335.5 | 351.6 | 399.8 | 358.8 | 303.6 | 238.1 | 119.6 | 105.2 | 2993.4 |
United States Boston | 163.4 | 168.4 | 213.7 | 227.2 | 267.3 | 286.5 | 300.9 | 277.3 | 237.1 | 206.3 | 143.2 | 142.3 | 2633.6 |
United States Charlotte | 173.3 | 180.3 | 234.8 | 269.6 | 292.1 | 289.2 | 290.0 | 272.9 | 241.4 | 230.5 | 178.4 | 168.5 | 2821.0 |
United States Chicago | 135.8 | 136.2 | 187.0 | 215.3 | 281.9 | 311.4 | 318.4 | 283.0 | 226.6 | 193.2 | 113.3 | 106.3 | 2508.4 |
United States Cleveland | 101.0 | 122.3 | 167.0 | 216.0 | 263.6 | 294.6 | 307.2 | 262.2 | 219.0 | 169.5 | 89.8 | 67.8 | 2280.0 |
United States Columbus | 110.6 | 126.3 | 162.0 | 201.8 | 243.4 | 258.1 | 260.9 | 235.9 | 212.0 | 183.1 | 104.2 | 84.3 | 2182.6 |
United States Dallas | 183.5 | 178.3 | 227.7 | 236.0 | 258.4 | 297.8 | 332.4 | 304.5 | 246.2 | 228.1 | 183.8 | 173.0 | 2849.7 |
United States Denver | 215.3 | 211.1 | 255.6 | 276.2 | 290.0 | 315.3 | 325.0 | 306.4 | 272.3 | 249.2 | 194.3 | 195.9 | 3106.6 |
United States Detroit | 119.9 | 138.3 | 184.9 | 217.0 | 275.9 | 301.8 | 317.0 | 283.5 | 227.6 | 176.0 | 106.3 | 87.7 | 2435.9 |
United States El Paso | 254.5 | 263.0 | 326.0 | 348.0 | 384.7 | 384.1 | 360.2 | 335.4 | 304.1 | 298.6 | 257.6 | 246.3 | 3762.5 |
United States Fresno | 141.5 | 196.9 | 286.2 | 335.5 | 398.9 | 412.2 | 428.2 | 399.6 | 345.9 | 302.3 | 189.9 | 127.1 | 3564.2 |
United States Honolulu | 213.5 | 212.7 | 259.2 | 251.8 | 280.6 | 286.1 | 306.2 | 303.1 | 278.8 | 244.0 | 200.4 | 199.5 | 3035.9 |
United States Houston | 143.4 | 155.0 | 192.5 | 209.8 | 249.2 | 281.3 | 293.9 | 270.5 | 236.5 | 228.8 | 168.3 | 148.7 | 2577.9 |
United States Indianapolis | 132.1 | 145.7 | 178.3 | 214.8 | 264.7 | 287.2 | 295.2 | 273.7 | 232.6 | 196.6 | 117.1 | 102.4 | 2440.4 |
United States Jacksonville | 189.4 | 193.8 | 257.9 | 286.4 | 303.9 | 283.6 | 282.0 | 262.4 | 228.2 | 214.6 | 193.9 | 183.6 | 2879.7 |
United States Kansas City | 183.7 | 174.3 | 223.9 | 257.8 | 285.0 | 305.5 | 329.3 | 293.9 | 240.5 | 213.6 | 155.3 | 147.1 | 2809.9 |
United States Las Vegas | 245.2 | 246.7 | 314.6 | 346.1 | 388.1 | 401.7 | 390.9 | 368.5 | 337.1 | 304.4 | 246.0 | 236.0 | 3825.3 |
United States Los Angeles | 225.3 | 222.5 | 267.0 | 303.5 | 276.2 | 275.8 | 364.1 | 349.5 | 278.5 | 255.1 | 217.3 | 219.4 | 3254.2 |
United States Louisville | 140.5 | 148.9 | 188.6 | 221.1 | 263.4 | 288.9 | 293.6 | 272.6 | 234.3 | 208.5 | 135.7 | 118.3 | 2514.4 |
United States Memphis | 166.6 | 173.8 | 215.3 | 254.6 | 301.5 | 320.6 | 326.9 | 307.0 | 251.2 | 245.9 | 173.0 | 151.9 | 2888.3 |
United States Miami | 219.8 | 216.9 | 277.2 | 293.8 | 301.3 | 288.7 | 308.7 | 288.3 | 262.2 | 260.2 | 220.8 | 216.1 | 3154.0 |
United States Milwaukee | 140.2 | 151.5 | 185.4 | 213.5 | 275.5 | 304.5 | 321.1 | 281.2 | 215.1 | 178.0 | 112.8 | 104.8 | 2483.6 |
United States Minneapolis | 156.7 | 178.3 | 217.5 | 242.1 | 295.2 | 321.9 | 350.5 | 307.2 | 233.2 | 181.0 | 112.8 | 114.3 | 2710.7 |
United States Nashville | 139.6 | 145.2 | 191.3 | 231.5 | 261.8 | 277.7 | 279.0 | 262.1 | 226.4 | 216.8 | 148.1 | 130.6 | 2510.1 |
United States New Orleans | 153.0 | 161.5 | 219.4 | 251.9 | 278.9 | 274.3 | 257.1 | 251.9 | 228.7 | 242.6 | 171.8 | 157.8 | 2648.9 |
United States New York City | 162.7 | 163.1 | 212.5 | 225.6 | 256.6 | 257.3 | 268.2 | 268.2 | 219.3 | 211.2 | 151.0 | 139.0 | 2534.7 |
United States Nome | 62.2 | 140.1 | 205.0 | 245.3 | 290.3 | 275.3 | 250.3 | 178.1 | 153.6 | 116.7 | 66.4 | 53.0 | 2036.3 |
United States Oklahoma City | 200.8 | 189.7 | 244.2 | 271.3 | 295.2 | 326.1 | 356.6 | 329.3 | 263.7 | 245.1 | 186.5 | 180.9 | 3089.4 |
United States Omaha | 167.8 | 157.6 | 206.4 | 230.1 | 277.1 | 314.0 | 332.5 | 296.3 | 245.5 | 217.5 | 148.0 | 134.1 | 2726.9 |
United States Philadelphia | 155.7 | 154.7 | 202.8 | 217.0 | 245.1 | 271.2 | 275.6 | 260.1 | 219.3 | 204.5 | 154.7 | 137.7 | 2498.4 |
United States Phoenix | 256.0 | 257.2 | 318.4 | 353.6 | 401.0 | 407.8 | 378.5 | 360.8 | 328.6 | 308.9 | 256.0 | 244.8 | 3871.6 |
United States Pittsburgh | 93.9 | 108.5 | 155.4 | 182.8 | 217.4 | 242.2 | 254.9 | 228.4 | 196.7 | 167.3 | 99.4 | 74.4 | 2021.3 |
United States Portland (OR) | 85.6 | 116.4 | 191.1 | 221.1 | 276.1 | 290.2 | 331.9 | 298.1 | 235.7 | 151.7 | 79.3 | 63.7 | 2340.9 |
United States Raleigh | 163.8 | 173.1 | 228.9 | 250.7 | 258.4 | 267.7 | 259.5 | 239.6 | 217.6 | 215.4 | 174.0 | 157.6 | 2606.3 |
United States Richmond (VA) | 172.5 | 179.7 | 233.3 | 261.6 | 288.0 | 306.4 | 301.4 | 278.9 | 237.9 | 222.8 | 183.5 | 163.0 | 2829.0 |
United States Sacramento | 145.5 | 201.3 | 278.0 | 329.6 | 406.3 | 419.5 | 440.2 | 406.9 | 347.8 | 296.7 | 194.9 | 141.1 | 3607.8 |
United States Salt Lake City | 127.4 | 163.1 | 241.9 | 269.1 | 321.7 | 360.5 | 380.5 | 352.5 | 301.1 | 248.1 | 150.4 | 113.1 | 3029.4 |
United States San Antonio | 159.4 | 169.7 | 215.5 | 209.7 | 221.8 | 275.9 | 308.8 | 293.9 | 234.9 | 218.0 | 171.9 | 149.7 | 2629.2 |
United States San Diego | 239.3 | 227.4 | 261.0 | 276.2 | 250.5 | 242.4 | 304.7 | 295.0 | 253.3 | 243.4 | 230.1 | 231.3 | 3054.6 |
United States San Francisco | 185.9 | 207.7 | 269.1 | 309.3 | 325.1 | 311.4 | 313.3 | 287.4 | 271.4 | 247.1 | 173.4 | 160.6 | 3061.7 |
United States Seattle | 69.8 | 108.8 | 178.4 | 207.3 | 253.7 | 268.4 | 312.0 | 281.4 | 221.7 | 142.6 | 72.7 | 52.9 | 2169.7 |
United States St. Louis | 161.2 | 158.3 | 198.3 | 223.5 | 266.5 | 291.9 | 308.9 | 269.8 | 236.1 | 208.4 | 140.9 | 129.9 | 2593.7 |
United States Tampa | 199.9 | 202.7 | 267.5 | 299.1 | 314.5 | 277.8 | 265.3 | 249.5 | 223.0 | 233.9 | 201.7 | 191.6 | 2926.5 |
United States Tucson | 259.9 | 258.2 | 320.7 | 357.2 | 400.8 | 396.9 | 342.7 | 335.6 | 316.4 | 307.4 | 264.4 | 245.8 | 3806.0 |
United States Tulsa | 175.8 | 171.7 | 219.6 | 244.4 | 266.7 | 294.8 | 334.7 | 305.3 | 232.5 | 218.6 | 161.1 | 160.8 | 2786.0 |
United States Virginia Beach | 171.5 | 175.2 | 229.3 | 252.8 | 271.7 | 280.1 | 278.3 | 260.4 | 231.4 | 208.3 | 175.7 | 160.4 | 2695.1 |
United States Washington D.C. | 144.6 | 151.8 | 204.0 | 228.2 | 260.5 | 283.2 | 280.5 | 263.1 | 225.0 | 203.6 | 150.2 | 133.0 | 2527.7 |
United States Wichita | 190.9 | 186.4 | 230.4 | 257.8 | 289.8 | 305.0 | 342.1 | 309.2 | 245.6 | 226.3 | 170.2 | 168.7 | 2922.4 |
United States Yuma | 268.4 | 270.8 | 335.5 | 365.5 | 407.4 | 415.4 | 392.6 | 375.6 | 341.7 | 319.6 | 270.1 | 252.7 | 4015.3 |