Как подсчитать вхождение строки в файл для всех файлов в каталоге и вывести в новый файл с помощью оболочки - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть сотни файлов в каталоге, которые я хотел бы подсчитать вхождение строки в каждом файле.

Я бы хотел, чтобы вывод представлял собой сводный файл, содержащий исходное имя файла плюс счетчик (в идеале в одной строке)

, например

file1 6

file2 3

file3 4

et c

Спасибо за внимание

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Спасибо за подробный ответ, он дает мне идеи для будущих проектов.

В моем случае все файлы имели одинаковый формат (вывод из другого скрипта) и единственные файлы в каталоге.

Я нашел ответ в другой теме

grep - c -R 'xxx'

0 голосов
/ 04 апреля 2020

ВНИМАНИЕ : Я большой энтузиаст c любитель, поэтому возьмите все с долей соли.

Несколько вопросов к вам - в зависимости от ваших ответов, решение ниже может потребоваться некоторая корректировка.

  1. Все ли ваши файлы находятся в одном каталоге, или вам также нужно просмотреть подкаталоги и подкаталоги и т. д. c.? Ниже я сделаю самое простое предположение - все ваши файлы находятся в одном каталоге.

  2. Являются ли все ваши файлы текстовыми файлами? В приведенном ниже примере каталог будет содержать текстовые файлы, исполняемые файлы, символьные ссылки c и каталоги; количество будет дано только для текстовых файлов. (В любом случае linux считают текстовыми файлами.)

  3. Могут быть файлы, которые вообще не содержат искомую строку. Они не включены в вывод ниже. Вам тоже нужно их показывать со счетом 0?

  4. Я предполагаю, что под "подсчетом вхождений" вы подразумеваете их все - даже если строка встречается несколько раз на одном и том же линия. (Вот почему простой grep -c его не обрежет, поскольку он учитывает только строки, содержащие подстроку, независимо от того, сколько раз каждая.)

  5. Нужно ли включать скрытые файлы (чье имя начинается с точки)? В моем коде ниже я предположил, что вы этого не сделаете.

  6. Вас волнует, что сначала отображается счетчик, а затем имя файла?

Хорошо, вот так.

[oracle@localhost test]$ ls -al
total 20
drwxr-xr-x.  3 oracle oinstall   81 Apr  3 18:42 .
drwx------. 39 oracle oinstall 4096 Apr  3 18:42 ..
-rw-r--r--.  1 oracle oinstall   40 Apr  3 17:44 aa
lrwxrwxrwx.  1 oracle oinstall    2 Apr  3 18:04 bb -> aa
drwxr-xr-x.  2 oracle oinstall    6 Apr  3 17:40 d1
-rw-r--r--.  1 oracle oinstall   38 Apr  3 17:56 f1
-rw-r--r--.  1 oracle oinstall    0 Apr  3 17:56 f2
-rwxr-xr-x.  1 oracle oinstall  123 Apr  3 18:15 zfgrep
-rw-r--r--.  1 oracle oinstall   15 Apr  3 18:42 .zz

Вот команда для подсчета 'waca' в текстовых файлах в этом каталоге ( не рекурсивно). Я определяю переменную substr для хранения желаемой строки. (Обратите внимание, что это также может быть регулярное выражение, в более общем смысле - но я не проверял это, поэтому вам придется, если это ваш вариант использования.)

[oracle@localhost test]$ substr=waca
[oracle@localhost test]$ find . -maxdepth 1 -type f  \
> -exec grep -osHI "$substr" {} \; | sed "s/^\.\/\(.*\):$substr$/\1/" | uniq -c
      8 aa
      2 f1
      1 .zz

Объяснение: Я использую find чтобы найти только файлы в текущем каталоге (исключая каталоги, ссылки и все остальное, что у меня есть sh в каталоге). Это будет включать в себя скрытые файлы, а также двоичные файлы, а не только текст. В этом примере я find в текущем каталоге, но вы можете использовать любой путь вместо . Я ограничиваю глубину до 1, поэтому команда применяется только к файлам в текущем каталоге - поиск не является рекурсивным. Затем я передаю результаты на grep. -o означает поиск всех совпадений (даже если несколько совпадений на строку текста) и отображение каждого совпадения в отдельной строке. -s - для режима без вывода сообщений (на всякий случай grep думает о печати сообщений), -H - для включения имен файлов (даже если существует только один файл, соответствующий подстроке), а -I - для игнорирования двоичных файлов. .

Затем я передаю это sed, чтобы из каждой строки, выводимой grep, оставалось только имя файла без начального ./ и без завершающего :waca. Этот шаг может не понадобиться - если вы не возражаете против вывода, как это:

  8 ./aa:waca
  2 ./f1:waca
  1 ./.zz:waca

Затем я передаю вывод на uniq -c, чтобы получить счет.

Затем вы можете перенаправить вывод в файл, если это то, что вам нужно. (Оставлено как тривиальное упражнение - поскольку я забыл, что это было частью требования, извините.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...