
Задача состояла в том, чтобы найти количество вхождений символа «а» во всех файлах каталога (рекурсивно).
Мой сценарий был таким
find . -type f -exec grep -o 'a' {} \; 2>/dev/null | wc -l
но это не удалось: я получил результат 0, хотя на моем локальном компьютере это работало.
Что не так с этим скриптом? Думаю, он не пуленепробиваемый или что-то в этом роде. Как мне сделать его пуленепробиваемым или исправить?
решение1
Я предполагаю, что проблемная машина grep
не поддерживает -o.
Если это так, то ваша командная строка генерирует сообщение об ошибке каждый раз find
при execs grep
. Однако, поскольку стандартная ошибка перенаправляется в /dev/null, крики остаются глухими.
wc
не получает ни одного байта, в результате чего количество строк равно 0, поскольку grep
происходит немедленный выход.
Попробуйте запустить ваш конвейер без перенаправления stderr или с перенаправлением в файл журнала. Если я прав, вы должны увидеть одно сообщение об ошибке на каждый файл, найденный find
.
Если вы найдете это полезным, вот альтернатива, которая не использует grep
:
find . -type f -exec cat {} \; | tr -cd a | wc -m
Если вы find
поддерживаете более эффективную +
альтернативу exec:
find . -type f -exec cat {} + | tr -cd a | wc -m
решение2
Я сделал это:
find "${directory-.}" -type f -print0 | xargs -0 -r cat | grep -F -o 'a' | wc -l
что почти то же самое, что и ваша команда, и получило ненулевой результат. Вы в том каталоге, в котором думали? И вы на самом деле ищете a
? Если нет, я предлагаю grep -F
(как я и использовал) или fgrep
, чтобы искать фиксированную строку, а не регулярное выражение.
Вы можете еще больше упростить задачу с помощью grep -r
(рекурсивного grep):
grep -Fro 'a' "${directory-.} | wc -l
К сожалению, вы не можете grep
сделать подсчет, поскольку grep -o -c
считает строки, а не вхождения — я считаю это ошибкой.