#!/bin/bash echo process a given input depending on options in a pipeline echo -------------------------------------------------------------------------------- echo inputs=("2 xxx" "1 hi" "3 abc") # options to sort or limit the number of answers opt_sort=1 opt_limit=2 declare -p inputs declare -p opt_sort opt_limit echo -------------------------------------------------------------------------------- echo solution 1: manually check the option echo printf '%s\n' "${inputs[@]}" | # we can use an if if [ "$opt_limit" -gt 0 ]; then grep -m "$opt_limit" -P '^' ; else cat; fi | # or a more concise block { ((opt_sort)) && sort || cat ; } | sed -e 's/xxx/XXX/' echo -------------------------------------------------------------------------------- echo solution 2: use function that pipe to each other echo # we can declare functions which will handle the option # the functions are chained in the call, depending on the option # run the process and pipe to the chained commands or run the # chained command do_limit() { (($opt_limit)) && head -n "$opt_limit" | "$@" || "$@" ; } do_sort() { ((opt_sort)) && sort | "$@" || { [[ -n "$@" ]] && "$@" ; } ; } # a function with a simple operation, no option handles do_sed() { sed -e 's/xxx/XXX/' ; } printf '%s\n' "${inputs[@]}" | do_limit do_sort do_sed printf '%s\n' "${inputs[@]}" | do_limit do_sort cat | do_sed # the last option handling function needs a chained function # this wouldn't work # printf '%s\n' "${inputs[@]}" | do_limit do_sort echo -------------------------------------------------------------------------------- echo solution 3: create a function that runs a list of option handling functions echo do_all() { do_limit do_sort do_sed ; } printf '%s\n' "${inputs[@]}" | do_all printf '%s\n' "${inputs[@]}" | do_all | do_sed echo -------------------------------------------------------------------------------- echo solution 4: use list of commands, call directly echo # creating option handling functions with all the piping can be simplified create() { eval "$1() { $2 | \"\$@\" || \"\$@\" ; }" ; } # create another function that handle $opt_limit # equivalent to do_limit() { (($opt_limit)) && head -n "$opt_limit" | "$@" || "$@" ; } create do_limit2 '(($opt_limit)) && head -n "$opt_limit"' # we can put all the commands in a list commands=(do_limit2 do_sort) # this function will al the commands in the above list do_commands() { "${commands[@]}" cat ; } printf '%s\n' "${inputs[@]}" | do_commands printf '%s\n' "${inputs[@]}" | do_commands | do_sed echo -------------------------------------------------------------------------------- echo solution 5: use list of commands, pass them as arguments echo # we can also define a function that accepts a list of commands to run do_command_list() { "$@" cat ; } # the commands are passed as arguments printf '%s\n' "${inputs[@]}" | do_command_list "${commands[@]}" printf '%s\n' "${inputs[@]}" | do_command_list "${commands[@]}" | do_sed echo -------------------------------------------------------------------------------- echo solution 6: use list of commands, pass the list echo # we can also define a function that takes a list by name do_command_list_by_name() { local -n array=$1 ; "${array[@]}" cat ; } # we pass the list name printf '%s\n' "${inputs[@]}" | do_command_list_by_name commands printf '%s\n' "${inputs[@]}" | do_command_list_by_name commands | do_sed echo -------------------------------------------------------------------------------- echo solution 7: use list of commands, use temporary files echo run_commands() { PIPE1=$(mktemp) PIPE2=$(mktemp) >$PIPE1 cat for f in "$@" do >$PIPE2 ; <$PIPE1 $f >$PIPE2 || <$PIPE1 cat >&$PIPE2 t=$PIPE1 PIPE1=$PIPE2 PIPE2=$t done <$PIPE1 cat } echo -------------------------------------------------------------------------------- echo solution 8: eval pipes echo opt_limit=2 ; run_limit() { ((opt_limit)) && head -n "$opt_limit" ; } opt_sort=1 ; run_sort() { ((opt_sort)) && sort ; } pipe() { p="cat $(printf "| { %s || cat ; } " "$@")" ; eval "$p" ; } printf '%s\n' "2 xxx" "1 hi" "3 abc" | pipe run_limit run_sort echo -------------------------------------------------------------------------------- echo solution 9: eval pipes from array echo pipe_list() { p="cat $(printf "| { %s || cat ; } " "${run_list[@]}")" ; eval "$p" ; } run_list=(run_limit run_sort) printf '%s\n' "2 xxx" "1 hi" "3 abc" | pipe_list echo -------------------------------------------------------------------------------- echo solution 10: eval pipes from array passed as argument echo pipe_list_arh() { local -n list=$1 ; p="cat $(printf "| { %s || cat ; } " "${list[@]}")" ; eval "$p" ; } printf '%s\n' "2 xxx" "1 hi" "3 abc" | pipe_list run_list # vim: set filetype=bash :