Рекурсивный grep по сравнению с находкой / - типом f - должностное лицо grep {} \; Который более эффективен/быстрее?

С zsh.

zle-line-init() {
  ((SECONDS - last < 300)) && return
  LBUFFER="rm -R ./... "
  last=$SECONDS
  zle -R
}
zle -N zle-line-init

(для делания этого (самое большее) каждые 5 минут).

Мне не нравится идея команды, появляющейся внезапно в моей подсказке все же.

71
08.07.2016, 20:58
4 ответа
[1176036] Я не уверен:

grep -r -i "коричневая собака" /*

это действительно то, что ты имела в виду. Это означало бы рекурсивное grep во всех не скрытых файлах и каталогах в [1176434]/[1176435] (но все равно загляните внутрь скрытых файлов и каталогов в них).

Предположим, Вы имели в виду:

Несколько вещей, на которые стоит обратить внимание:

Не все реализации [1176904]grep[1176905] поддерживают [1176906]-r[1176907]. И среди тех, что поддерживают, поведение отличается: некоторые следуют сим-ссылкам на каталоги при обходе дерева каталогов (что означает, что Вы можете в конце концов искать несколько раз в одном и том же файле или даже запускаться в бесконечных циклах), некоторые нет. Некоторые будут искать внутри файлов устройств (и это займет некоторое время, например, в [1176908]/dev/zero[1176909]) или трубных или двоичных файлах... некоторые нет.

Это эффективно, так как [1176910]grep[1176911] начинает искать внутри файлов, как только обнаруживает их. Но пока она ищет в файле, она больше не ищет больше файлов для поиска (что, вероятно, так же хорошо в большинстве случаев)

Your:

(удалено [1176440]-r[1176441], что здесь не имеет смысла) ужасно неэффективна, так как вы запускаете по одному [1176442]grep[1176443] на файл. [1176444]; [1176445] следует использовать только для команд, которые принимают только один аргумент. Более того, т.к. [1176446]grep[1176447] ищет только в одном файле, он не будет печатать имя файла, поэтому вы не будете знать, где находятся совпадения.

Вы не ищете внутри файлов устройств, каналов, сим-каналов... вы не следуете по симлинкам, но потенциально вы все еще ищете внутри таких вещей, как [1176448]/proc/mem[1176449].

было бы намного лучше, потому что было бы выполнено как можно меньше команд [1176450]grep[1176451]. Вы получите имя файла, если только последний запуск не будет иметь только один файл. Для этого лучше использовать:

enter image description here

или с GNU [1176452]grep[1176453]:

Обратите внимание, что [1176454]grep[1176455] не будет запущен до тех пор, пока [1176456]find[1176457] не найдет достаточно файлов для его жевания, так что будет некоторая начальная задержка. И [1176458]find[1176459] не будет продолжать поиск большего количества файлов до тех пор, пока не вернется предыдущее grep [1176460]grep[1176461]. Распределение и передача большого списка файлов имеет некоторое (возможно, незначительное) влияние, поэтому в целом, вероятно, это будет менее эффективно, чем [1176462]grep -r[1176463], который не следует по симлинку и не заглядывает внутрь устройств.

С помощью инструментов GNU:

Как было сказано выше, будет запущено как можно меньше экземпляров [1176464]grep[1176465], но [1176466] find[1176467] продолжит поиск большего количества файлов, в то время как первый вызов [1176468]grep[1176469] ищет внутри первой партии. Однако это может быть или не быть преимуществом. Например, если данные хранятся на вращающихся жестких дисках, то [1176470]find[1176471] и [1176472]grep[1176473] доступ к данным, хранящимся в разных местах диска, приведет к замедлению пропускной способности диска, так как головка диска будет постоянно двигаться. В настройках RAID (где [1176474]find[1176475] и [1176476]grep[1176477] могут получить доступ к разным дискам) или на SSD, это может иметь положительное влияние.

$ play something.mp3
$ play something.wav

В настройках RAID выполнение нескольких одновременных вызовов [1176478]grep[1176481] также может улучшить ситуацию. Тем не менее, с помощью GNU-утилит на RAID1-хранилищах с 3-мя дисками

можно значительно увеличить производительность. Заметим, однако, что второе [1176482]grep[1176483] будет запущено только после того, как будет найдено достаточно файлов для заполнения первой команды [1176484]grep[1176485]. Можно добавить опцию [1176486]-n[1176487] к [1176488]xargs[1176489], чтобы это произошло быстрее (и передавать меньше файлов при вызове [1176490]grep[1176491]). Также обратите внимание, что если вы перенаправите вывод [1176492]xargs[1176493] на что-либо, кроме терминального устройства, то [1176494]greps[1176495]s начнут буферизацию своего вывода, что означает, что вывод этих [1176496]grep[1176497]s, скорее всего, будет некорректно чересстроен. Вам придется использовать [1176498]stdbuf -oL[1176499] (там, где это доступно, как в GNU или FreeBSD), чтобы обойти это (у вас все еще могут быть проблемы с очень длинными строками (обычно >4KiB)) или заставить каждого из них записать свой вывод в отдельный файл и в конце концов скомкаплектовать их все.

Здесь строка, которую вы ищете, исправлена (не регенерация), поэтому использование опции [1176500]-F[1176501] может иметь значение (маловероятно, так как реализации [1176502]grep[1176503] уже знают, как это оптимизировать).

Другая вещь, которая может иметь большое значение, это исправление локали на C, если вы находитесь в многобайтовой локали:

enter image description here

Чтобы избежать заглядывания внутрь [1176504]/proc[1176505], [1176506]/sys[1176507] .... используйте [1176508]-xdev[1176509] и укажите файловые системы, в которых вы хотите искать:


Или укажите пути, которые вы хотите явно исключить:enter image description here

89
27.01.2020, 19:31
[1175413] Если [1175806]*[1175807] в вызове [1175808]grep[1175809] для вас не важен, то первый должен быть более эффективным, так как запускается только один экземпляр [1175810]grep[1175811], а вилки не бесплатны. В большинстве случаев это будет быстрее даже с [1175812]*[1175813], но в крайних случаях сортировка может это изменить.[12162] Могут быть и другие структуры [1175814] найти [1175815]-[1175816]grep[1175817], которые лучше работают, особенно со многими маленькими файлами. Чтение большого количества файловых записей и inodes сразу может дать улучшение производительности на вращающихся носителях.[12163]Но давайте посмотрим на статистику syscall:[12164]find[12165]grep only[12166]
14
27.01.2020, 19:31
[1177099] Еще один момент, на который следует обратить внимание, следующий. Будет ли какая-нибудь из директорий, через которые [1177553]grep[1177554] должен рекурсивно пройти, содержать больше файлов, чем указано в настройках [1177555]nofile[1177556] вашей системы? (например, количество открытых файловых дескрипторов, по умолчанию 1024 на большинстве дистрибутивов linux)

Если да, то [1177557]найти[1177558] определенно можно, так как некоторые версии [1177559]grep[1177560] взорвутся с ошибкой [1177561]Argument list too long[1177562] при попадании в каталог с большим количеством файлов, чем установлено максимальное количество открытых файловых дескрипторов.

Только мои 2 очага.[1177106]

-1
27.01.2020, 19:31

Если вы находитесь на SSD и время поиска пренебрежимо мало, вы можете воспользоваться параллельным GNU:

find /path -type f | parallel --gnu --workdir "$PWD" -j 8 '
    grep -i -r 'the brown dog' {} 
'

Это приведет к выполнению до 8 grep-процессов в одно и то же время, основываясь на том, что find found.

Это приведет к повреждению жесткого диска, но SSD должен хорошо с ним справляться.

5
27.01.2020, 19:31

Теги

Похожие вопросы