Algo como isso deve fazer o que você quer:
for cmd in cat head tail; do
cmdLoc=$(type $cmd | awk '{print $3}')
eval "
$cmd() {
for fn in \"\$@\"; do
source-highlight --failsafe --out-format=esc -o STDOUT -i \"\$fn\" |
$cmdLoc -
done
}
"
done
Você pode condensar assim:
for cmd in cat head tail; do
cmdLoc=$(type $cmd |& awk '{print $3}')
eval "$cmd() { for fn in \"\$@\"; do source-highlight --failsafe --out-format=esc -o STDOUT -i \"\$fn\" | $cmdLoc - ; done }"
done
Exemplo
Com o acima em um script de shell, chamado tst_ccmds.bash
.
#!/bin/bash
for cmd in cat head tail; do
cmdLoc=$(type $cmd |& awk '{print $3}')
eval "$cmd() { for fn in \"\$@\"; do source-highlight --failsafe --out-format=esc -o STDOUT -i \"\$fn\" | $cmdLoc - ; done }"
done
type cat
type head
type tail
Quando executo isso, recebo as funções definidas como você pediu:
$ ./tst_ccmds.bash
cat ()
{
for fn in "$@";
do
source-highlight --failsafe --out-format=esc -o STDOUT -i "$fn" 2> /dev/null | /bin/cat - ;
done
}
head is a function
head ()
{
for fn in "$@";
do
source-highlight --failsafe --out-format=esc -o STDOUT -i "$fn" 2> /dev/null | /usr/bin/head - ;
done
}
tail is a function
tail ()
{
for fn in "$@";
do
source-highlight --failsafe --out-format=esc -o STDOUT -i "$fn" 2> /dev/null | /usr/bin/tail -;
done
}
Em ação
Quando eu uso essas funções no meu shell ( source ./tst_ccmds.bash
) elas funcionam da seguinte maneira:
gato
cabeça
cauda
textosimples
Qual é o truque?
O maior truque, e eu o chamaria mais de um truque, é o uso de um traço ( -
) como um argumento para cat
, head
e tail
através de um duto que os força para produzir o conteúdo que veio de source-highlight
através de STDIN do pipe. Este pouco:
...STDOUT -i "$fn" | /usr/bin/head - ....
O outro truque é usar a opção --failsafe
de source-highlight
:
--failsafe
if no language definition is found for the input, it is simply
copied to the output
Isso significa que, se uma definição de idioma não for encontrada, ela funcionará como cat
, simplesmente copiando sua entrada para a saída padrão.
Nota sobre aliases
Esta função falhará se head
, tail
ou cat
forem aliases porque o resultado da chamada type
não apontará para o executável. Se você precisar usar essa função com um alias (por exemplo, se desejar usar less
, que requer que o sinalizador -R
seja colorido), será necessário excluir o alias e adicionar o comando de aliasmente separadamente:
less(){
for fn in "$@"; do
source-highlight --failsafe --out-format=esc -o STDOUT -i "$fn" |
/usr/bin/less -R || /usr/bin/less -R "$fn"; done
}