
Na documentação xargs
há menção a um "replstr" que o -I
sinalizador utiliza. Comecei a ler sobre isso quando encontrei este comando para executar fswatch
:
fswatch -0 -e ".*" -i ".rb" . | xargs -0 -n 1 -I {} ruby {}
e comecei a ler a página de manual doxargs
-I replstr
Execute utility for each input line, replacing one or more occurrences of replstr in up to replacements (or 5 if no -R flag is
specified) arguments to utility with the entire line of input. The resulting arguments, after replacement is done, will not be
allowed to grow beyond 255 bytes; this is implemented by concatenating as much of the argument containing replstr as possible, to
the constructed arguments to utility, up to 255 bytes. The 255 byte limit does not apply to arguments to utility which do not
contain replstr, and furthermore, no replacement will be done on utility itself. Implies -x.
Pensar no termo "replstr" parece que provavelmente significa algo como "ler avaliar cadeia de loop de impressão", é para isso que é a abreviação? Comecei a brincar com ele para tentar ter uma ideia do que {}
está fazendo, mas não tenho certeza se realmente entendi ainda:
➜ scripts git:(master) ✗ {0..3}
zsh: command not found: 0..3
➜ scripts git:(master) ✗ echo {0..3}
0 1 2 3
➜ scripts git:(master) ✗ echo {a..3}
a ` _ ^ ] \ [ Z Y X W V U T S R Q P O N M L K J I H G F E D C B A @ ? > = < ; : 9 8 7 6 5 4 3
➜ scripts git:(master) ✗ echo {a..d}
a b c d
➜ scripts git:(master) ✗ echo cats and dogs | xargs
cats and dogs
➜ scripts git:(master) ✗ echo cats and dogs | xargs {}
xargs: {}: No such file or directory
➜ scripts git:(master) ✗ echo cats and dogs | xargs {} echo {}
xargs: {}: No such file or directory
➜ scripts git:(master) ✗ echo cats and dogs | xargs -I {}
➜ scripts git:(master) ✗ echo cats and dogs | xargs -I {} echo {}
cats and dogs
Por exemplo echo {a..3}
, realmente não faz sentido para mim. Definitivamente parece que está fazendo algo no sentido de "substituir esta lista de strings aqui", mas não tenho certeza se essa é a maneira correta de ver isso. Além disso, não tenho certeza se {}
é um tipo específico de replstr e se há mais ou se um replstr é apenas algo entre um par de chaves. Adoraria alguma orientação sobre replstr e como abordá-los.
Responder1
replstr
significa "string de substituição" ou "string de substituição".
O replstr original é {}
. Foi introduzido pela primeira vez com a cláusula find
de comando exec
onde foi substituído por cada nome de arquivo encontrado, por exemplo
find /tmp -name "foo*" -exec echo file {} found \;
será exibido, assumindo que dois arquivos correspondam ao padrão:
file foo1 found
file foo2 found
O xargs
comando permite fazer o mesmo com argumentos construídos a partir de strings passadas para sua entrada padrão, e também permite especificar algo diferente de {}
uma string de substituição.
Observe que o replstr padrão não tem {}
nada entre chaves, sendo este último usado para finalidades diferentes, por exemplo, intervalos como você já notou ou expansão de parâmetros.
Responder2
O -I
argumento funciona assim: -I whatever
significa que as ocorrências literalmente de whatever
são substituídas pelo argumento do comando. Demonstração:
$ echo "a
b
c" | xargs -I f echo hey f hey f
hey a hey a
hey b hey b
hey c hey c
Ver? xargs
pegou cada uma das linhas a
, b
, e c
, e as substituiu no lugar de f
in echo hey f hey f
.
Não há nenhum {}
envolvido.
A -I
opção é POSIX. GNU xargs
documenta uma -i
opção obsoleta que, se invocada como -iwhatever
se comporta como -I whatever
. Se invocado apenas, -i
ele se comporta como -I {}
. Neste caso, as ocorrências de {}
são substituídas. {}
é claramente inspirado por uma característica de find
: seu -exec
predicado.
A sintaxe {a..b}
e foo{a,b,c}bar
Bash processada por sua "expansão de chaves". {}
não tem nenhum significado especial e é passado para um comando como está. (Se não fosse, quebraria find
as invocações comuns e em conformidade com os padrões.)
Responder3
O {...}
é oexpansão da chave do shell, que suporta listas como {a,b,c}
(expande para a
, b
e c
) e sequências de números como {0..13}
(expande para números 0
, 1
... 12
, 13
) ou caracteres {a..d}
( a
, b
, c
, d
). (A expansão de chaves não tem nada a ver com o {}
espaço reservado usado por xargs
).
A sequência um tanto estranha que {a..3}
se expande é explicada pelaTabela de caracteres ASCII. Como a
não é um número, ambos são considerados caracteres, e a expansão são todos os caracteres entre a
e 3
pelo valor numérico dos códigos de caracteres. Acontece que a
vem depois de 3
, então a sequência é descendente através das letras maiúsculas e dos números de 9 a 3.
Como visto, misturar letras e números em um intervalo como esse não é muito útil, mas {a..z}
ou {A..Z}
pode ser, assim como similares [a-z]
e [A-Z]
em regexes e shell globs. (Isto é, se você puder ignorar o resto das letras.)