Это в основном не по теме, но вы можете использовать
find -maxdepth 1 -type f -name '*.txt' | xargs python -c '
import fileinput
for line in fileinput.input(inplace=True):
print line.replace("blah", "blee"),
'
Главное преимущество здесь (над ... xargs ... -I {} ... sed ...
) - скорость: вы избегаете вызывать sed
10 миллионов раз. Было бы еще быстрее, если бы вы могли избежать использования Python (так как python довольно медленный), поэтому Perl может быть лучшим выбором для этой задачи. Я не уверен, как сделать эквивалент удобно с Perl.
Это работает так, что xargs
будет вызывать Python с таким количеством аргументов, сколько может поместиться в одной командной строке, и продолжит делать это до тех пор, пока у него не закончатся аргументы (которые предоставляются ls -f *.txt
). Количество аргументов для каждого вызова будет зависеть от длины имен файлов и некоторых других вещей. Функция fileinput.input
выдает последовательные строки из файлов, названных в аргументах каждого вызова, а опция inplace
говорит ему "волшебным образом" перехватить вывод и использовать его для замены каждой строки.
Обратите внимание, что метод replace
строк в Python не использует регулярные выражения; если вам это нужно, вы должны import re
и использовать print re.sub(line, "blah", "blee")
. Это Perl-совместимые RegExps, которые являются сильно укрепленными версиями тех, что вы получаете с помощью sed -r
.
редактировать
Как упоминает Акира в комментариях, оригинальная версия, использующая glob (ls -f *.txt
) вместо команды find
, не будет работать, потому что globs обрабатываются самой оболочкой (bash
). Это означает, что перед выполнением команды в командной строке будет подставлено 10 миллионов имен файлов. Это почти наверняка превысит максимальный размер списка аргументов команды. Вы можете использовать xargs --show-limits
для системной информации по этому вопросу.
Максимальный размер списка аргументов также учитывается xargs
, который ограничивает количество аргументов, которые он передает каждому вызову python, в соответствии с этим пределом. Поскольку xargs
все равно придется вызывать python несколько раз, предложение akira использовать os.path.walk
для получения списка файлов, вероятно, сэкономит вам некоторое время.