Sim (quase) e não. Bash não suporta pipelining 'objects' em primeiro lugar - seus pipelines, mesmo os internos, ainda são construídos em subprocessos e stdio comum (que é um bytestream), e então você só pode interagir com linhas comuns de text (por exemplo, uma lista linha por linha de caminhos de arquivos), não objetos complexos.
Assim, o equivalente mais próximo seria while read -r <var>; do ...; done
. Mais sobre isso depois.
Sua tarefa específica pode ser melhor tratada usando um simples loop for <var> in <words>
com curingas :
for file in *; do
if [[ $file == *.py ]]; then
do_something_with "$file"
elif [[ $file == *.pdf ]]; then
do_something_else --with "$file"
fi
done
Você nem precisa reproduzir as verificações explícitas - você pode ter dois loops:
for file in *.py; do
do_something_with "$file"
done
for file in *.pdf; do
do_something_else --with "$file"
done
Para fazer o mesmo recursivamente , você pode a) usar curingas recursivas do Bash:
shopt -s globstar
for file in **/*; do
if ...; then ...; fi
done
ou b) use find
e faça o loop de cada linha em stdin :
find . -type f | while read -r file; do
if [[ $file == *.py ]]; then
...
fi
done
(Sim, eu deveria ter usado IFS="" read -r <var>
para lidar com nomes de arquivos que acabam com um espaço - mas, felizmente, não tenho nenhum deles no meu sistema, então não vou me incomodar.)
Mais uma vez, você pode pular as verificações manuais de nome de arquivo e solicitar o que precisa antes.
shopt -s globstar
for file in **/*.pdf; do
do_something_with "$file"
done
Variante b:
find . -type f -name "*.pdf" | while read -r file; do
do_something_with "$file"
done
O mesmo, mas fazendo uso da opção -exec do find :
find . -type f -name "*.pdf" -exec do_something_with {} \;