.Dd November 3, 2017 .Dt XE 1 .Os .Sh NAME .Nm xe .Nd execute a command for every argument .Sh SYNOPSIS .Nm .Op Fl 0FLRnqv .Oo Fl I Ar replace-arg Oc .Op Fl N Ar maxargs .Op Fl j Ar maxjobs .Ar command\ ... .Nm .Op Ar flags\ ... .Fl p Ar pattern Ar command\ ... .Oo Cm \&+ Ar pattern Ar command\ ... Oc Ns ... .Nm .Op Ar flags\ ... .Fl f Ar argfile Ar command\ ... .Nm .Op Ar flags\ ... .Fl s Ar shellscript .Nm .Op Ar flags\ ... .Fl a Ar command\ ... Cm -- Ar args\ ... .Nm .Op Ar flags\ ... .Fl A Ar argsep Ar command\ ... Ar argsep Ar args\ ... .Sh DESCRIPTION The .Nm utility constructs command lines from specified arguments, combining some of the best features of .Xr xargs 1 and .Xr apply 1 . .Pp .Nm means .Dq execute for every ... . .Pp .Nm supports different methods to specify arguments to commands: .Bl -tag -width Ds .It Ar command\ ... By default, arguments - separated by newlines - are read from the standard input. The resulting command is constructed from the command line parameters, replacing .Ar replace-arg with the read argument, and is executed with .Xr execvp 3 . .Pp In this mode, no shell is involved and .Ar replace-arg must appear as a word on its own, i.e. .Sq foo {} bar will work, but .Sq foo{} bar will not, where {} is the default value for .Ar replace-arg . .Pp If no argument is specified, the default is .Sq Ic printf %s\en . .It Fl f Ar argfile Read arguments from .Ar argfile , instead of the standard input. .Pp This does not close the standard input for execution, it is passed to the forked process. .It Fl s Ar shellscript In this mode, the single parameter .Ar shellscript is executed using .Ic sh -c . In the script, the specified arguments can be accessed using $1, $2, ... .Pp For example: .Dl echo \(aqa\enb\(aq | xe -N2 \-s \(aqecho $2 $1\(aq .It Fl a Ar command\ ... Cm -- Ar args\ ... In this mode, everything after .Cm -- is passed as .Ar args to .Ar command . .It Fl A Ar argsep Ar command\ ... Ar argsep Ar args\ ... Same as .Fl a , but the custom argument separator .Ar argsep is used to distinguish between .Ar command and its .Ar args . .El .Pp The options are as follows: .Bl -tag -width Ds .It Fl 0 Input filenames are separated by NUL bytes (instead of newlines, which is the default) .It Fl F Fatal: stop and exit when a command execution fails. .It Fl L Run the resulting commands with line-buffered output; lines from two jobs will not interleave. When used twice, or with .Fl vv , also prefix each line with the number of the job (see .Sx ENVIRONMENT ) in such a manner that the output can be piped to .Sq Li sort -snk1 to group it. .It Fl R Return with status 122 when no arguments have been specified (instead of 0, the default). .Nm never executes a command when no arguments are specified. .It Fl n Dry run: don't run the resulting commands, just print them. .It Fl q Quiet mode: redirect standard output and standard error of commands to /dev/null. .It Fl v Verbose: print commands to standard error before running them. When used twice, also print job id and exit status for each command. .It Fl p Enable .Xr make 1 Ns \&- Ns style percent rules. The first argument of .Ar command\ ... is regarded as a pattern, see .Sx PERCENT RULES below. Patterns without a slash (or .Sq Li \&*\&* ) are matched against the basenames only. .Pp Multiple runs of patterns and commands are separated by .Sq Li \&+ . Only the first matching percent rule is executed; in case no pattern matches, no command is run. .It Fl I Ar replace-arg Replace first occurrence of .Ar replace-arg (default: .Cm {} ) in the resulting command with the argument(s). Pass an empty .Ar replace-arg to disable the replace function. Contrary to .Xr xargs 1 this will expand into multiple arguments when needed. .It Fl N Ar maxargs Pass up to .Ar maxargs arguments to each command (default: 1). .br Using .Fl N0 will pass as many arguments as possible. .It Fl j Ar maxjobs Run up to .Ar maxjobs processes concurrently. Using .Fl j0 will run as many processes as there are CPU cores running. If .Ar maxjobs ends with an .Sq Ic x , it is regarded as a multiplier of the number of running CPU cores (rounded down, but using at least one core). .El .Sh PERCENT RULES The percent rules of .Nm are similar to the globs of .Xr sh 1 or .Xr fnmatch 3 : .Sq Li \&? matches a single character that is not .Sq Li \&/ . .Sq Li \&/ matches one or multiple .Sq Li \&/ in the string. .Sq Li \&* matches zero or more characters, but never .Sq Li \&/ . .Sq Li \&*\&* matches zero or more characters, including .Sq Li \&/ . Note that all of these also match leading dots in file names. .Pp .Sq Li \&{ Ns Va a Ns \&, Ns Va b Ns \&, Ns Va c Ns \&} matches either .Va a , b or .Va c . .Sq Li \&[ Ns Va abc Ns \&] matches one of the characters .Va abc (but never .Sq Li \&/ ) . .Sq Li \&[ Ns \&! Ns Va abc Ns \&] matches all characters but .Va abc . Alternatively, .Sq Li \&[ Ns \&^ Ns Va abc Ns \&] can be used too. .Sq Li \&[ Ns Va a Ns \&- Ns Va c Ns \&] matches any character in the range between .Va a and .Va c inclusive. In character ranges, characters can be escaped using a backslash. .Pp In the pattern, a single occurrence of .Sq Li \&% matches one or more characters, and replaces the first occurrence of .Sq Li \&% with the matched string in the remaining arguments, which are then used as the command to be executed. .Sh ENVIRONMENT The environment variable .Ev ITER is passed to the child process and incremented on each command execution. .Sh EXIT STATUS .Nm follows the convention of GNU and OpenBSD xargs: .Bl -tag -compact -width Ds .It 0 on success .It 123 if any invocation of the command exited with status 1 to 125. .It 124 if the command exited with status 255 .It 125 if the command was killed by a signal .It 126 if the command cannot be run .It 127 if the command was not found .It 1 if some other error occurred .El .Pp Additionally, 122 is returned when .Fl R was passed and the command was never executed. .Sh EXAMPLES Compress all .c files in the current directory, using all CPU cores: .Dl xe -a -j0 gzip -- *.c Remove all empty files, using .Xr lr 1 : .Dl lr -U -t 'size == 0' | xe -N0 rm Convert .mp3 to .ogg, using all CPU cores: .Dl xe -a -j0 -s 'ffmpeg -i \&"${1}\&" \&"${1%.mp3}.ogg\&"' -- *.mp3 Same, using percent rules: .Dl xe -a -j0 -p %.mp3 ffmpeg -i %.mp3 %.ogg -- *.mp3 Similar, but hiding output of ffmpeg, instead showing spawned jobs: .Dl xe -ap -j0 -vvq '%.{m4a,ogg,opus}' ffmpeg -y -i {} out/%.mp3 -- * .Sh SEE ALSO .Xr apply 1 , .Xr parallel 1 , .Xr xapply 1 , .Xr xargs 1 .Sh AUTHORS .An Leah Neukirchen Aq Mt leah@vuxu.org .Sh LICENSE .Nm is in the public domain. .Pp To the extent possible under law, the creator of this work has waived all copyright and related or neighboring rights to this work. .Pp .Lk http://creativecommons.org/publicdomain/zero/1.0/