Suponha que você tentou algo assim:
$ paste ../data/file-{A,B,C}.dat
e perceba que deseja classificar cada arquivo (numericamente, digamos) antes de colar. Então, usando a substituição de processo, você precisa escrever algo assim:
$ paste <(sort -n ../data/file-A.dat) \
<(sort -n ../data/file-B.dat) \
<(sort -n ../data/file-C.dat)
Aqui você vê muita duplicação, o que não é bom. Como cada substituição de processo é isolada uma da outra, não é possível usar nenhuma expansão de chaves ou de nome de caminho (curingas) que abranja várias substituições de processos.
Existe uma ferramenta que permite escrever isso de forma compacta (por exemplo, dando sort -n
e ../data/file-{A,B,C}.dat
separadamente) e compor toda a linha de comando para você?
Responder1
Você poderia fazer:
eval paste '<(sort -n ../data/file-'{A,B,C}'.dat)'
Ou para automatizá-lo como uma função
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
(em algumas ksh
implementações, você precisa substituir local
por typeset
)
Para se adaptar a qualquer comando arbitrário (e para provar que eval
pode ser seguro quando usado corretamente), você poderia fazer:
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
Responder2
Por favor, vejaaqui, por que eval
pode ser perigoso usar. Como você notará, é umferramenta muito poderosa, mas ao mesmo tempo podecausar muitos danos.
O script a seguir fará o que você deseja - com segurança.
sort_ps ()
{
local cmd="$1" p=()
shift;
for f in "$@"; do
p+=(<(sort -n "$f"));
done
"$cmd" "${p[@]}"
}
EDITAR: O Sr. Chazelas está certo. Eu consertei minha solução, então agora você pode usar sort_ps paste file1.txt file2.txt file2.txt ... fileN.txt
. Obrigado Stephane por revisar minha resposta.
Exemplo de saída:
rany$ sort_ps sprunge foo1.txt foo.txt
http://sprunge.us/EBZf?/dev/fd/62
http://sprunge.us/TQGC?/dev/fd/62