Как найти и рассчитать, сколько файлов содержит определенное слово?

Для демона, что Вы хотите, процесс, который не имеет никакой связи ни с чем. По крайней мере Вы хотите, чтобы это было на его собственной сессии, не присоединено к терминалу, не имело любой дескриптор файла, наследованный от родителя, открытого для чего-либо, не имело родителя, заботящегося о Вас (кроме init), имеют текущий каталог в / чтобы не предотвратить umount...

Для отсоединения от терминала Вы создаете новую сессию, однако, для создания сессии, Вы не должны быть группой (или сессия) лидер, настолько лучше всего должен разветвить новый процесс. Принятие родительских выходов, который также означает, что процесс не будет больше иметь родителя и будет принят init. Затем закройте все возможные дескрипторы файлов, Вас chdir("/") (нельзя закрыть текущий рабочий каталог для выпуска того ресурса как для дескрипторов файлов, делая / текущие рабочие каталоги, по крайней мере, не предотвращают размонтировавшиеся каталоги).

Поскольку тот процесс является лидером сессии, существует риск, что, если он когда-нибудь открывает оконечное устройство, это становится процессом управления того терминала. Разветвление во второй раз гарантирует, что этого не происходит.

На другом конце, и, в интерактивных оболочках, ветвлениях и создает новую группу процесса (чтобы не быть в группе приоритетного процесса терминала), и в неинтерактивных оболочках, разветвляет процесс и игнорирует SIGINT в нем. Это не отсоединяется от терминала, не закрывает дескрипторы файлов (хотя некоторые оболочки вновь откроют stdin для /dev/null)...

7
13.10.2013, 02:02
3 ответа

В первую очередь, как другие сказали, нет никакой причины использовать find, просто используйте рекурсивный grep:

grep -irm 1 carrot . | wc -l 

-m 1 гарантирует это grep прекратит искать каждый файл после первого соответствия. Без него Вы не считаете количество файлов, которые содержат carrot но количество строк, тот же файл будет считаться многократно, если это будет содержать несколько экземпляров carrot. От man grep:

    -r, --recursive
          Read all files  under  each  directory,  recursively,  following
          symbolic  links  only  if they are on the command line.  This is
          equivalent to the -d recurse option.
   -i, --ignore-case
          Ignore  case  distinctions  in  both  the  PATTERN and the input
          files.  (-i is specified by POSIX.)
   -m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines. 

Если Вы действительно, действительно хотите сделать это с находкой, Вы могли бы сделать

find . -type f -exec grep -im 1 carrot {} \; | wc -l

Обратите внимание, что я указываю -type f так как Вы не хотите grep каталоги.

13
27.01.2020, 20:14
  • 1
    Это не корректно. Обеспечение -m 1 остановится после одного соответствия, не одного соответствия на файл. Таким образом, это будет на самом деле всегда возвращаться 1. Я думаю, что второе решение делает это правильно все же. –  Phonon 11.11.2015, 20:13
  • 2
    @Phonon не, это не будет, попробуйте его. По крайней мере, в моей системе Linux, это находит первое соответствие в каждом файле. grep -r все еще соглашения с отдельными файлами, это не делает просто cat все они. –  terdon♦ 11.11.2015, 20:32

Найдите, что количество файлов содержит морковь слова

number_of_files=`grep -l -r -i "carrot" . | wc -l`

Значение для grep аргументы:

-l, --files-with-matches
         Only the names of files containing selected lines are written to standard output.  grep will only search a file until a match has been found, making
         searches potentially less expensive.  Pathnames are listed once per file searched.  If the standard input is searched, the string ``(standard
         input)'' is written.

-R, -r, --recursive
         Recursively search subdirectories listed.

-i : case insenstive

wc -l : распечатывает количество строк, переданных как вход программе. В нашем случае эти строки являются названиями файлов с соответствием входному набору, найденному grep.

Распечатайте вывод

echo $number_of_files
4
27.01.2020, 20:14
  • 1
    @Downvoter для комментария причины? –  smRaj 13.10.2013, 02:28
  • 2
    я не сделал downvote, но это не считает количество файлов, которые содержат строку, это считает количество строк, которые содержат его. Если файл будет иметь три строки, которые соответствуют шаблону, который Вы ищете, то это будет считаться три раза. Кроме того, Вам не нужно wc с тех пор grep имеет -c опция. Добавить -c и -m 1 избегать дублирующихся соответствий. –  terdon♦ 13.10.2013, 02:33
  • 3
    @terdon: у Меня нет достаточной репутации для комментария ответа. Так, я помещаю его здесь, OP нужно общее количество файлов, которые содержат слово "морковь". Ваш grep -ircm 1 carrot . не дает количество файлов, которые содержат строку. Вместо этого-c опция обеспечивает количество соответствий для искавшего шаблона, который это нашло на основание файла. Пример; filename1:count filename2:count . Я не уверен, Ваш ответ будет полезным для цели, которую требует OP –  smRaj 13.10.2013, 03:02
  • 4
    @terdon: Дополнительно с grep -ircm 1 carrot ., grep распечатывает имена файлов, даже если он не содержит carrot с нулем как количество как: file_name1:0 file_name2:0 –  smRaj 13.10.2013, 03:06
  • 5
    Вы совершенно правы, поделом мне для регистрации слишком быстро, спасибо. -l лучше, чем -m также, но эй, я буду придерживаться своего пути, так как Вы уже используете его :) –  terdon♦ 13.10.2013, 03:09

Вариант решения smRaj был бы двойным вызовом grep. Следующее дало бы тот же результат как grep [и т.д.] | туалет-l:

grep -l -r -i "carrot" . | grep -c .

Следующее распечатало бы пронумерованный список файлов, содержащих искавшее слово.

grep -l -r -i "carrot" . | grep -n .
3
27.01.2020, 20:14
  • 1
    +1, я собирался ответить на точное некоторая вещь, когда я видел, что у Вас уже есть :) –  Joseph R. 13.10.2013, 13:25

Теги

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