No caso específico de printf, você sempre pode fazer:
echo {1..8} | xargs printf 'the number %s comes before %s\n'
porque printfpossui uma xargscapacidade intrínseca de executar várias vezes se receber mais argumentos do que o necessário para uma única invocação. Embora isso tenha pouca vantagem sobre
printf 'the number %s comes before %s\n' {1..8}
E para listas grandes, o xargscomando simples pode resultar na xargsexecução de várias instâncias printf, algumas das quais podem ter números ímpares de argumentos. Você pode passar -n 1000para xargsse proteger contra isso, onde 1000 é um número par que deve ser pequeno o suficiente para não atingir o limite muito longo da lista de argumentos e grande o suficiente para evitar a execução de tantos printfs.
Observe que xargschamaria, não o built-in do seu shell printf, mas o externo printf, com cada chamada em um novo processo separado.
Observe também que, para uma entrada vazia, exceto em alguns BSDs, ela ainda seria executada printfuma vez sem argumento. GNU xargse compatível têm uma opção -r
(ou --no-run-if-empty) para evitar isso.
Para ficar claro, essa resposta simples é específica para o seu printfexemplo e não funcionaria no caso geral em que você deve passar dois parâmetros de cada vez ao seu comando (como seria o caso diff, por exemplo). Para resolver o problema geral zsh, você pode usar:
for i j ({1..8}) echo "the number $i comes before $j"