У меня есть каталог, в котором есть 10144911 файлов. До сих пор я пробовал следующее:
for f in ls; do sed -i -e 's/blah/blee/g' $f; done
Разбился мой снаряд, ls
он в тильде, но я не могу понять, как его сделать.
ls | xargs -0 sed -i -e 's/blah/blee/g'
Слишком много аргументов для sed
find . -name "*.txt" -exec sed -i -e 's/blah/blee/g' {} \;
Не могу больше разветвляться, больше нет памяти
Любые другие идеи о том, как создать такую добрую команду? Файлы не должны общаться друг с другом. ls | wc -l
кажется, работает (очень медленно), поэтому это должно быть возможно.
sed
для каждого файла. Я не уверен, есть ли способ открывать, редактировать, сохранять и закрывать ряд файловsed
; если скорость важна, вы можете использовать другую программу, например, Perl или Python.sed
, вероятно, быстрее, чем запускpython
илиperl
также, за исключением случаев, когда вы делаете все в этом интерпретаторе.Ответы:
Попробуйте это:
Он будет передавать только одно имя файла на каждый вызов
sed
. Это решит проблему «слишком много аргументов для седа».-P
Вариант должен позволить нескольким процессам быть раздвоенной одновременно. Если 0 не работает (он должен работать как можно больше), попробуйте другие числа (10? 100? Количество ядер у вас?), Чтобы ограничить число.источник
find . -name \*.txt -print0
избегать того, чтобы оболочка расширяла глобус и пыталась выделить место для 10 миллионов аргументов для поиска .Я протестировал этот метод (и все остальные) на 10 миллионах (пустых) файлах, с именами «hello 00000001» или «hello 10000000» (14 байтов на имя).
ОБНОВЛЕНИЕ: я теперь включил четырехъядерный запуск
'find |xargs'
метода (все еще без 'sed'; просто echo> / dev / null) ..Вот краткое изложение того, как предоставленные ответы оказались эффективными при выполнении с данными испытаний, упомянутыми выше. Эти результаты включают только основные накладные расходы; т.е. «седь» не назывался. Процесс sed почти наверняка будет самым трудоемким, но я подумал, что было бы интересно посмотреть, как сравниваются голые методы.
Денниса
'find |xargs'
Метод , использующий одно ядро, занял * 4 часа 21 минуту ** дольше, чемbash array
метод наno sed
ходу ... Однако преимущество многоядерности, предоставляемое 'find', должно перевесить разницу во времени, показанную при вызове sed обработка файлов ...источник
Еще одна возможность для совершенно безопасного поиска :
источник
Это в основном не по теме, но вы можете использовать
Основным преимуществом здесь (сверх
... 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 обрабатываются самой shell (bash
). Это означает, что перед выполнением команды в командной строке будет подставлено 10 миллионов имен файлов. Это в значительной степени гарантированно превышает максимальный размер списка аргументов команды. Вы можете использоватьxargs --show-limits
для системной информации об этом.Максимальный размер списка аргументов также принимается во внимание
xargs
, что ограничивает количество аргументов, которые он передает каждому вызову python в соответствии с этим пределом. посколькуxargs
все еще придется вызывать python несколько раз, предложение Акиры использовать егоos.path.walk
для получения списка файлов, вероятно, сэкономит вам некоторое время.источник
os.path.walk()
?.
и..
. Конечно, есть другие способы сделать это (то естьfind
), но я стараюсь максимально близко придерживаться того, что понимает ОП. Это также причина не использоватьos.path.walk
.os.path.walk
довольно легко.Пытаться:
источник
ls -f
было бы лучше; Вы действительно хотите подождатьstat()
и отсортировать столько файлов?