#!/usr/bin/env bash # each.sh — run a command for each item. Replaces v1 `each`. # # Two input modes: # each.sh [ARG2 ... ARGN] — args as items # | each.sh — stdin lines as items (one per line) # # The literal token {} in CMD, if present, gets replaced with the current item. # Otherwise the item is appended as the last arg. # # Examples: # each.sh 'echo got:' /etc/hosts /etc/passwd # tbn adt | awk 'NR>1{print $2}' | each.sh 'echo route_test for' {} # nc-find.sh --process codametrix --format tsv \ # | awk -F'\t' 'NR>1{print $2}' \ # | each.sh 'lib/nc-msgs.sh' {} '--limit' '1' '--format' 'count' # # Each invocation is a separate process; failures are not aggregated. To # stop on first error, prepend `set -e` in your own wrapper. set -o pipefail usage() { sed -n '2,20p' "$0"; exit 0; } [ $# -ge 1 ] || usage case "$1" in -h|--help) usage ;; esac CMD="$1"; shift run_one() { local item="$1" if [[ "$CMD" == *"{}"* ]]; then eval "${CMD//\{\}/\"\$item\"}" else # Append item as last arg eval "$CMD \"\$item\"" fi } if [ $# -gt 0 ]; then for item in "$@"; do run_one "$item"; done else while IFS= read -r item; do [ -z "$item" ] && continue run_one "$item" done fi