The reason that your command does not work is that the command substitution (the bit you wrote with backticks) would be executed once, before xargs
is even started.
Since you tagged this with xargs
, I thought I'd give an xargs
-based solution.
First, to unpack a single one of your tar
archives, you could use
dir=${archive%.tar}
mkdir -- "$dir" && tar -x -f "$archive" -C "$dir"
... assuming that $archive
contains the filename of the tar
archive and that the archive is plain (not compressed).
You could obviously loop this with
for archive in *.tar; do
dir=${archive%.tar}
mkdir -- "$dir" && tar -x -f "$archive" -C "$dir"
done
but that would not let us use some of the commonly (albeit non-standard) features of xargs
, such as running multiple commands in parallel.
To run our initial commands, four at a time, the names of the tar
archives has to be fed into xargs
on its standard input.
We can do that with
printf '%s\n' *.tar | xargs ...
This obviously assumes that no archive has a name that contains embedded newlines, but you could work around that by using
printf '%s\0' *.tar | xargs -0 ...
if your implementation of xargs
supports the non-standard -0
option for reading nul-terminated arguments.
To run the unpacking in from xargs
, it would be easiest to do in in a sh -c
child shell:
printf '%s\0' *.tar |
xargs -0 -P 4 -I {} sh -c 'dir=${1%.tar}; mkdir -- "$dir" && tar -x -f "$1" -C "$dir"' sh {}
Within the sh -c
shell script, $1
would be the same as $archive
in our initial command, and the script would be started once for each archive. The -P 4
option to xargs
would run four extractions in parallel, if your implementation of xargs
supports the -P
option.