Isso é principalmente fora do tópico, mas você pode usar
find -maxdepth 1 -type f -name '*.txt' | xargs python -c '
import fileinput
for line in fileinput.input(inplace=True):
print line.replace("blah", "blee"),
'
O principal benefício aqui (acima de ... xargs ... -I {} ... sed ...
) é a velocidade: você evita invocar sed
10 milhões de vezes. Seria ainda mais rápido se você pudesse evitar o uso do Python (já que o Python é relativamente lento), então o perl pode ser uma escolha melhor para essa tarefa. Não sei como fazer o equivalente convenientemente com o perl.
A maneira como isso funciona é que xargs
invocará o Python com tantos argumentos quantos couberem em uma única linha de comando e continuará fazendo isso até ficar sem argumentos (que estão sendo fornecidos por ls -f *.txt
). O número de argumentos para cada invocação dependerá do tamanho dos nomes dos arquivos e, algumas outras coisas. A função fileinput.input
produz linhas sucessivas dos arquivos nomeados nos argumentos de cada invocação, e a opção inplace
diz a ela para "pegar" magicamente a saída e usá-la para substituir cada linha.
Observe que o método replace
da string do Python não usa regexps; Se você precisar deles, precisará import re
e usar print re.sub(line, "blah", "blee")
. Eles são RegExps Perl-Compatible, que são versões muito fortificadas daquelas que você obtém com sed -r
.
editar
Como akira menciona nos comentários, a versão original usando um glob ( ls -f *.txt
) no lugar do comando find
não funcionaria porque os globs são processados pelo próprio shell ( bash
). Isso significa que antes que o comando seja executado, 10 milhões de nomes de arquivos serão substituídos na linha de comando. Isso é praticamente garantido para exceder o tamanho máximo da lista de argumentos de um comando. Você pode usar xargs --show-limits
para informações específicas do sistema sobre isso.
O tamanho máximo da lista de argumentos também é levado em conta por xargs
, o que limita o número de argumentos que ele passa para cada invocação de python de acordo com esse limite. Como xargs
ainda terá que invocar Python algumas vezes, a sugestão de akira de usar os.path.walk
para obter a listagem de arquivos provavelmente economizará algum tempo.