Невозможно запустить команду cat в CentOS (список аргументов слишком длинный) - PullRequest
2 голосов
/ 20 января 2020

У меня есть папка, в которой около 300 тыс. Файлов, каждый файл содержит 2-3 Мб. Теперь я хочу запустить команду, чтобы найти число символов char {в оболочке

Моя команда:

nohup cat *20200119*| grep "{" | wc -l > /mpt_sftp/mpt_cdr_ocs/file.txt

Это прекрасно работает с небольшим количеством файлов. Когда я запускаю папку, в которой у меня есть все файлы (файлы 300 КБ), она показывает

Аргумент слишком длинный

Ответы [ 2 ]

1 голос
/ 20 января 2020

Не могли бы вы попробовать следующее:

find . -maxdepth 1 -type f -name "*20200119*" -print0 | xargs -0 grep -F -o "{" | wc -l > /mpt_sftp/mpt_cdr_ocs/file.txt

Я на самом деле протестировал 300 000 файлов с именами из 10 символов, и он работает хорошо.

  • xargs автоматически настраивает длину списка аргументов, подаваемого на grep, и нам не нужно об этом беспокоиться. (Вы можете увидеть, как выполняется команда grep, если для параметра -t установить значение xargs.)
  • Параметр -F значительно ускоряет выполнение grep для поиска фиксированного значения. строка, а не регулярное выражение.
  • Опция -o понадобится, если символ { появляется несколько раз в строке и вы хотите считать их по отдельности.
1 голос
/ 20 января 2020

Максимальный размер списка аргументов варьируется, но обычно это что-то вроде 128 КиБ или 256 КиБ. Это означает, что у вас очень много файлов, если часть *20200119* переполняет список максимального аргумента. Но вы говорите «около 3 файлов lakhs», что составляет около 300 000 - каждый файл содержит по крайней мере 8-символьную строку даты, плюс достаточно других символов, чтобы сделать имя уникальным, поэтому список имен файлов будет слишком длинным даже для самого большого вероятного «максимального размера списка аргументов».

Обратите внимание, что часть вашей команды nohup cat не имеет смысла (см. UUo C: Бесполезное использование Cat ); Вы должны использовать grep '{' *20200119*, чтобы сохранить ненужную передачу всех этих данных по каналу. Однако это также может привести к проблемам с слишком длинным списком аргументов.

Возможно, вам придется использовать вариант следующей команды, чтобы получить желаемый результат без переполнения командной строки:

find . -depth 1 -name '*20200119*' -exec grep '{' {} + | wc -l

При этом используется функция POSIX find, которая группирует столько аргументов, сколько уместится в командной строке, без переполнения для запуска grep на большом (но не слишком большом) количестве файлов, а затем передает выходные данные grep дает команду wc. Если вас беспокоят имена файлов, появляющиеся в выходных данных, подавьте их с помощью grep -h.

. Или вы можете использовать:

find . -depth 1 -name '*20200119*' -exec grep  -c -h '{' {} + |
awk '{sum += $1} END {print sum}'

grep -c -h в macOS производит простое число (количество строк, содержащих не менее одного {) в его стандартном выводе для каждого файла, указанного в его списке аргументов; то же самое делает GNU grep. Сценарий awk суммирует эти числа и печатает результат.

Использование -depth 1 поддерживается find в macOS; также -maxdepth 1 - они эквивалентны. GNU find не поддерживает -depth 1. Было бы лучше использовать -maxdepth 1. POSIX find поддерживает только -depth без номера. Вероятно, вы получите лучшее сообщение об ошибке при использовании -maxdepth 1 с find, который поддерживает только минимальный набор параметров POSIX, чем при использовании -depth 1.

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