Suppose you tried something like this:
$ paste ../data/file-{A,B,C}.dat
and realize that you want to sort each file (numerically, let's suppose) before pasting. Then, using process substitution, you need to write something like this:
$ paste <(sort -n ../data/file-A.dat) \
<(sort -n ../data/file-B.dat) \
<(sort -n ../data/file-C.dat)
Here you see a lot of duplication, which is not a good thing. Because each process substitution is isolated from one another, you cannot use any brace expansion or pathname expansion (wildcards) that spans multiple process substitution.
Is there a tool that allows you to write this in a compact way (e.g. by giving sort -n
and ../data/file-{A,B,C}.dat
separately) and composes the entire command line for you?
You could do:
eval paste '<(sort -n ../data/file-'{A,B,C}'.dat)'
Or to automate it as a function
sort_paste() {
local n i cmd
n=1 cmd=paste
for i do
cmd="$cmd <(sort -n -- \"\${$n}\")"
n=$(($n + 1))
done
eval "$cmd"
}
sort_paste ../data/file-{A,B,C}.dat
(in some ksh
implementations, you need to replace local
with typeset
)
To adapt to any arbitrary command, (and to prove that eval
can be safe when used properly), you could do:
xproc() {
local n i cmd stage stage1 stage2 stage3
cmd= xcmd= stage=1 n=1
stage1='cmd="$cmd \"\${$n}\""'
stage2='xcmd="$xcmd \"\${$n}\""'
stage3='cmd="$cmd <($xcmd \"\${$n}\")"'
for i do
if [ -z "$i" ] && [ "$stage" -le 3 ]; then
stage=$(($stage + 1))
else
eval 'eval "$stage'"$stage\""
fi
n=$(($n + 1))
done
eval "$cmd"
}
xproc paste '' sort -n -- '' ../data/file-{A,B,C}/dat
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments