Skip to main content
added 8 characters in body
Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r region TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$region" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all regions even if you started the script at 10:46:59.9 and it takes over 0.1 seconds¹ to run.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh², you can get both keys and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop once over all entries, that completely defeats the purpose and becomes significantly worse both functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' America/Santiago 'Tierra Del Fuego' America/Argentina/Ushuaia ) for zoneregion TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do zone=$region=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do zone=$1region=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the CSV heredoc approach mentioned above. Instead of a here doc, you could also have the CSV with the mapping in a separate file which could be maintained separately from the script, and use < /path/to/that/file instead of << 'EOF'...EOF.


¹ Or hours for instance because it's piped to a command that doesn' read its input in a while.

² Where the equivalent of bash printf's %T would be via its strftime builtin (and the $EPOCHSECONDS variable) or prompt expansion like with print -rP -- "$zone"$region %D{...}" (though only for the current time with the latter).

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r region TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$region" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all regions even if you started the script at 10:46:59.9 and it takes over 0.1 seconds¹ to run.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh², you can get both keys and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop once over all entries, that completely defeats the purpose and becomes significantly worse both functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' America/Santiago 'Tierra Del Fuego' America/Argentina/Ushuaia ) for zone TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do zone=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do zone=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the CSV heredoc approach mentioned above. Instead of a here doc, you could also have the CSV with the mapping in a separate file which could be maintained separately from the script, and use < /path/to/that/file instead of << 'EOF'...EOF.


¹ Or hours for instance because it's piped to a command that doesn' read its input in a while.

² Where the equivalent of bash printf's %T would be via its strftime builtin (and the $EPOCHSECONDS variable) or prompt expansion like with print -rP -- "$zone %D{...}" (though only for the current time with the latter).

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r region TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$region" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all regions even if you started the script at 10:46:59.9 and it takes over 0.1 seconds¹ to run.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh², you can get both keys and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop once over all entries, that completely defeats the purpose and becomes significantly worse both functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' America/Santiago 'Tierra Del Fuego' America/Argentina/Ushuaia ) for region TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do region=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do region=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the CSV heredoc approach mentioned above. Instead of a here doc, you could also have the CSV with the mapping in a separate file which could be maintained separately from the script, and use < /path/to/that/file instead of << 'EOF'...EOF.


¹ Or hours for instance because it's piped to a command that doesn' read its input in a while.

² Where the equivalent of bash printf's %T would be via its strftime builtin (and the $EPOCHSECONDS variable) or prompt expansion like with print -rP -- "$region %D{...}" (though only for the current time with the latter).

added 237 characters in body
Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r zoneregion TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$zone""$region" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all zonesregions even if you started the script at 10:46:59.9 and it takes over 0.1 seconds¹ to run.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh¹², you can get both keykeys and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop once over all entries anyway, that completely defeats the purpose and becomes significantly worse both functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' 'AmericaAmerica/Santiago'Santiago 'Tierra Del Fuego' 'AmericaAmerica/Argentina/Ushuaia'Ushuaia ) for zone TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do zone=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do zone=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the CSV heredoc approach mentioned above. Instead of a here doc, you could also have the CSV with the mapping in a separate file which could be maintained separately from the script, and use < /path/to/that/file instead of << 'EOF'...EOF.


¹ Or hours for instance because it's piped to a command that doesn' read its input in a while.

² Where the equivalent of bash printf's %T would be via its strftime builtin (and the $EPOCHSECONDS variable) or prompt expansion like with print -rP -- "$zone %D{...}" (though only for the current time with the latter).

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r zone TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$zone" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all zones.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh¹, you can get both key and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop over all entries anyway, that completely defeats the purpose and becomes significantly worse functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' 'America/Santiago' 'Tierra Del Fuego' 'America/Argentina/Ushuaia' ) for zone TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do zone=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do zone=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the CSV heredoc approach mentioned above. Instead of a here doc, you could also have the CSV with the mapping in a separate file which could be maintained separately from the script, and use < /path/to/that/file instead of << 'EOF'...EOF.


¹ Where the equivalent of bash printf's %T would be via its strftime builtin or prompt expansion like with print -rP -- "$zone %D{...}" (though only for the current time with the latter).

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r region TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$region" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all regions even if you started the script at 10:46:59.9 and it takes over 0.1 seconds¹ to run.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh², you can get both keys and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop once over all entries, that completely defeats the purpose and becomes significantly worse both functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' America/Santiago 'Tierra Del Fuego' America/Argentina/Ushuaia ) for zone TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do zone=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do zone=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the CSV heredoc approach mentioned above. Instead of a here doc, you could also have the CSV with the mapping in a separate file which could be maintained separately from the script, and use < /path/to/that/file instead of << 'EOF'...EOF.


¹ Or hours for instance because it's piped to a command that doesn' read its input in a while.

² Where the equivalent of bash printf's %T would be via its strftime builtin (and the $EPOCHSECONDS variable) or prompt expansion like with print -rP -- "$zone %D{...}" (though only for the current time with the latter).

added 19 characters in body
Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r zone TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$zone" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all zones.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh¹, you can get both key and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop over all entries anyway, that completely defeats the purpose and becomes significantly worse functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' 'America/Santiago' 'Tierra Del Fuego' 'America/Argentina/Ushuaia' ) for zone TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do zone=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do zone=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the CSV heredoc approach mentioned above. Instead of a here doc, you could also have the CSV with the mapping in a separate file which could be maintained separately from the script, and use < /path/to/that/file instead of << 'EOF'...EOF.


¹ Where the equivalent of bash printf's %T would be via its strftime builtin or prompt expansion like with print -rP -- "$zone %D{...}" (though only for the current time with the latter).

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r zone TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$zone" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all zones.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh¹, you can get both key and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop over all entries anyway, that completely defeats the purpose and becomes significantly worse functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' 'America/Santiago' 'Tierra Del Fuego' 'America/Argentina/Ushuaia' ) for zone TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do zone=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do zone=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the heredoc approach mentioned above.


¹ Where the equivalent of bash printf's %T would be via its strftime builtin or prompt expansion like with print -rP (though only for the current time with the latter).

Maybe an associative array is not the best tool here, you could do:

#! /bin/bash - export TZ while IFS=: read -r zone TZ; do printf '%s: %(%H:%M%p, %A, %d %B, %Y)T\n' "$zone" -2 done << 'EOF' Chile:America/Santiago Tierra Del Fuego:America/Argentina/Ushuaia ... EOF 

Note that -2 for bash printf's %T format directive refers to the time that bash instance was started. That makes sure you get an output for the same time in all zones.

You can iterate over the keys of an associative arrays in bash with:

for key in "${!assoc[@]}"; do value=${assoc[$key]} ... done 

But beware the order is non-deterministic.

In zsh¹, you can get both key and values at the same time with:

for key value in "${(kv@)assoc}"; do ... done 

But there as well, the order is non-deterministic.

Associative arrays are useful to look-up individual values efficiently. There's a higher cost upon assignment as a hash table needs to be built, but the look up is efficient. Here, as you want to loop over all entries anyway, that completely defeats the purpose and becomes significantly worse functionally and performance-wise. A normal array would make more sense.

In zsh:

list=( 'Chile' 'America/Santiago' 'Tierra Del Fuego' 'America/Argentina/Ushuaia' ) for zone TZ in $list; do ... done 

Bash doesn't support looping with more than one variable, but you can do:

for (( i = 0; i < ${#list[@]}; i += 2 )); do zone=${list[i]} TZ=${list[i+1]} ... done 

Instead there. Or:

set -- "${list[@]}" while (( $# )); do zone=$1 TZ=$2 ... shift 2 done 

But that's more cumbersome to write than the CSV heredoc approach mentioned above. Instead of a here doc, you could also have the CSV with the mapping in a separate file which could be maintained separately from the script, and use < /path/to/that/file instead of << 'EOF'...EOF.


¹ Where the equivalent of bash printf's %T would be via its strftime builtin or prompt expansion like with print -rP -- "$zone %D{...}" (though only for the current time with the latter).

added 779 characters in body
Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k
Loading
added 779 characters in body
Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k
Loading
Source Link
Stéphane Chazelas
  • 587.9k
  • 96
  • 1.1k
  • 1.7k
Loading