Se você quiser que aliases sejam expandidos após xargs , você pode fazer:
alias xargs='xargs '
No entanto, observe que apenas a primeira palavra após xargs está sujeita à expansão de alias e que pode ter efeitos inesperados se você tiver aliases para comandos padrão.
$ alias xargs='xargs ' a='echo test'
$ set -x
$ echo x | xargs a
+ echo x
+ xargs echo test
test x
$ echo x | xargs -r a
+ echo x
+ xargs -r a
xargs: a: No such file or directory
Você pode querer chamar seu alias de outra coisa e usar um comportamento padrão mais sensato para xargs . Por exemplo, com o GNU xargs :
alias axargs='xargs -r -d "\n" '
Agora, a substituição do processo se expande para um argumento: o nome de um arquivo que, para <(...) , contém a saída do comando (como uma transmissão ao vivo).
Com a saída de find , isso é útil apenas para comandos que aceitam como argumento um nome de arquivo esperado para conter uma lista de arquivos delimitada por nova linha.
feh é um deles:
feh -f <(find . -mtime -1 -type f -name '*.jpg')
Isso só funciona se os nomes de arquivo não contiverem caracteres de nova linha.
A implementação GNU de xargs tem uma opção -a para obter a lista de argumentos de um arquivo e combinada com -0 e a opção -print0 (ou -exec printf '%sfind' {} + ) para cmdB permite passar uma lista de nomes de arquivos de forma confiável:
xargs -r0a <(find ... -print0) feh....
Isso não ajuda em seu problema de alias.
Agora, se você quiser passar a saída de um comando como argumento (s) para outro comando, é aí que você usaria a substituição comando ao invés de processar substituição. Cuidado com algumas advertências embora.
cmdA "$(cmdB)"
passa a saída de cmdA , sem os caracteres de nova linha à direita como um argumento para * * /etc/passwd .jpg . Por exemplo, se você tiver três arquivos regulares (aqui com nomes incomuns embora perfeitamente válidos): foo.txt , <nl><nl> e <nl> (onde find . -type f significa um caractere de nova linha), a saída de cmdB ( ./* * /etc/passwd .jpg<nl>./foo.txt<nl>./<nl><nl><nl> ) será cmdA , então ./* * /etc/passwd .jpg<nl>./foo.txt<nl>./ receberá um argumento cmdA .
Isso provavelmente não é o que você quer. Você deseja que ./* * /etc/passwd receba cada nome de arquivo como argumentos separados: ./foo.txt , ./<nl><nl> e find .
Então, basicamente, você precisaria dividir a saída de cmdB nos nomes de arquivo individuais. Os shells POSIX têm um operador para isso, o operador split + glob que é invocado implicitamente quando você deixa uma substituição de comando (ou expansão de parâmetro ou expansão aritmética) sem aspas.
cmdA $(cmdB)
dividirá a saída de $IFS (sem os caracteres de nova linha à direita) nos caracteres ./* * /etc/passwd .jpg (por espaço padrão, guia e nova linha) e, então, cada palavra estará sujeita a globbing.
No nosso exemplo acima, não é isso que queremos. Isso dividiria ./* em * , /etc/passwd , .jpg e ./* e os * e find seriam adicionados à lista de arquivos no diretório atual.
O que queremos é dividir em caracteres de nova linha e não fazer parte da globbing. Isso é feito com:
IFS='
' # newline only
set -f
cmdA $(cmdB)
Isso ainda não funciona para nomes de arquivos contendo caracteres de nova linha. A saída de -print0 geralmente não é pós-processável, a menos que você use zsh ou você pode garantir que não haverá nomes de arquivo com caracteres de nova linha.
Agora, apenas "$(cmdB)" permite dividir em cmdB caracteres:
cmdA ${(0)"$(cmdB)"}
dividiria cmdA nas sequências de caracteres NUL. Ou:
IFS=$'cmdA ${$(find...):?no file}
' # no need for set -f in zsh
cmdA $(cmdB)
Outro problema com as abordagens de substituição de comandos é que se zsh falhar e / ou não produzir nada, zsh ainda será executado (sem argumento). Isso pode ser evitado com esta sintaxe (ainda com zsh ):
myalias ./**/*.jpg(.m-1)
Mas se você estiver usando find , geralmente não precisa ter todos os problemas, pois jpg suporta internamente a maior parte da funcionalidade de %code% . Por exemplo, você usaria:
alias xargs='xargs '
Para exibir os arquivos %code% modificados pela última vez nas últimas 24 horas.