foreach - Run an OS or shell command on each input line, similar to xargs


NAME

foreach - Run an OS or shell command on each input line, similar to xargs(1)


SYNOPSIS

foreach [OPTIONS] COMMAND [ARGS ...]


DESCRIPTION

Take each input line from stdin as DATA, and run COMMAND with DATA appended to the end of ARGS as a single argument.

If {} is there in ARGS then it's substituted with DATA rather than append to the end, unless --no-placeholder is given, because then {} is read literally. Additionally, foreach(1) parses DATA into fields and add each of them to the end of ARGS if --fields is given. Numbered placeholders, like {0}, {1}, ... are substituted with the respective field's value. A stand-alone {@} (curly bracket open, at sign, curly bracket close) argument is substituted to all fields as separate arguments.

So, for example, if you have not specified any ARGS in the command line and type both --data and --fields, then DATA goes into argv[1], and the first field goes into argv[2], second to argv[3] and so on. If have not given --data nor --fields, then --data is implied.

If called with --sh option, COMMAND is run within a shell context; input line goes to $DATA, individual fields go to ${FIELD[@]} (0-indexed).

Both in command and shell (--sh) modes, individual fields are available in $F0, $F1, ... environment variables.

Set -d DELIM if you want to split DATA not by $IFS but by other delimiter chars, eg. -d ',:' for comma and colon. There is also -t/--tab option to set delimiter to TAB for your convenience.


OPTIONS

-e, --sh

COMMAND is a shell script and for each DATA, it runs in the same shell context, so variables are preserved across invocations.

-l, --data

Pass DATA in the arguments after the user-specified ARGS.

-f, --fields

Pass individual fields of DATA in the arguments after DATA if --data is given, or after the user-specified ARGS if --data is not given.

-i, --input DATA

Don't read any DATA from stdin, but take DATA given at --input option(s). This option is repeatable.

-d, --delimiter DELIM

Cut up DATA into fields at DELIM chars. Default is $IFS.

-t, --tab

Cut up DATA into fields at TAB chars..

-P, --no-placeholder

Do not substitute {} with DATA.

-p, --prefix TEMPLATE

Print something before each command execution. TEMPLATE is a bash-interpolated string, may contain $DATA and ${FIELD[n]}. Probably need to put in single quotes when passing to foreach(1) by the invoking shell. It's designed to be evaluated, so backtick, command substitution, semicolon, and other shell expressions are eval'ed by bash.

--prefix-add TEMPLATE

Append TEMPLATE to the prefix template. See --prefix option.

--prefix-add-data

Add DATA to the prefix which is printed before each command execution. See --prefix option.

--prefix-add-tab

Add a TAB char to the prefix which is printed before each command execution. See --prefix option.

-v, --verbose
-n, --dry-run
-E, --errexit

Stop executing if a COMMAND returns non-zero. Rather exit with the said command's exit status code.


EXAMPLES

 ls -l --time-style +%FT%T%z | foreach --data --fields sh -c 'echo size: $5, file: $7'
 ls -l --time-style +%FT%T%z | foreach --sh 'echo size: ${FIELD[4]}, file: ${FIELD[6]}'


LIMITS

Placeholders for field values ({0}, {1}, ...) are considered from 0 up to 99. There must be a limit somewhere, otherwise I had to write a more complex replace routine.


CAVEATS

Placeholder {} is substituted in all ARGS anywhere, not just stand-alone {} arguments, but IS NOT ESCAPED! So be careful using it in shell command arguments like sh -e 'echo "data is: {}"'.


SEE ALSO

xargs(1), xe(1) https://github.com/leahneukirchen/xe, apply(1), xapply(1) https://www.databits.net/~ksb/msrc/local/bin/xapply/xapply.html

 foreach - Run an OS or shell command on each input line, similar to xargs