Bash functional: Difference between revisions

From wikinotes
Line 20: Line 20:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# Call callable/params($*), passing each each STDIN line as the last parameter
#
# EXAMPLE:
#  divisible_by_2() {
#      [ $(($1 % 2)) -eq 0 ] \
#          && echo "$1:yes" \
#          || echo "$2:no"
#  }
#
#  echo {1..4} | tr ' ' '\n' | map divisible_by_2
#
#  #> 1:no
#  #> 2:yes
#  #> 3:no
#  #> 4:yes
#
map() {
map() {
    # Call callable/params($*), passing each each STDIN line as the last parameter
     local input
     local input


Line 28: Line 43:
     done
     done
}
}
</syntaxhighlight>
{{ expand
| Example
|
<syntaxhighlight lang="bash">
print_if_divisible_by_2() {
    if [ $(($1 % 2)) -eq 0 ] ; then
        echo "$1:yes"
    else
        echo "$1:no"
    fi
}
echo {1..4} | tr ' ' '\n' | map print_if_divisible_by_2
#> 1:no
#> 2:yes
#> 3:no
#> 4:yes
</syntaxhighlight>
}}
</blockquote><!-- Map -->
</blockquote><!-- Map -->



Revision as of 19:32, 11 December 2022

Fancy loops that let you process things incrementally in a pipeline.
You'll almost never use these directly, but it might be inspiration for a more useful function.

Filter

# filters out results not matching 'grep foo'
find . \
  | while read line; do \
    echo $line | grep foo && echo "$line"; \
  done

Map

NOTE:

If your callable accepts parameter as stdin, you don't need map (ex. grep/sed work just fine from stdin).

# Call callable/params($*), passing each each STDIN line as the last parameter
#
# EXAMPLE:
#   divisible_by_2() {
#       [ $(($1 % 2)) -eq 0 ] \
#           && echo "$1:yes" \
#           || echo "$2:no"
#   }
#
#   echo {1..4} | tr ' ' '\n' | map divisible_by_2
#
#   #> 1:no
#   #> 2:yes
#   #> 3:no
#   #> 4:yes
#
map() {
    local input

    while read -r input; do
        "$@" "${input}"
    done
}
</blockquote><!-- Map -->

= Reduce =
<blockquote>
<syntaxhighlight lang="bash">
# callable/params must accept aggregate as 2nd-last param, and input as last param.
#
# EXAMPLE:
#   sum() { echo $(($1 + $2)) }
#   echo {1..10} | tr ' ' '\n' | reduce sum 0
#   #> 55
#
reduce() {
    local callable="${@:1:-1}" # all until last param
    local aggregate="${@[-1]}" # last param
    local input

    while read -r input; do
        aggregate="$("${callable[@]}" "${aggregate}" "${input}")"
    done
    echo "${aggregate}"
}