Intereting Posts
Невозможно «набить» команды на созданный «экран» сразу после создания на точки подключения к локальной файловой системе Как конвертировать несколько файлов XCF в PNG? Могу ли я получить общие гиперссылки в руководствах Info? Что означает этот , начинающийся с многих строк во время экрана загрузки Linux? Изменить порядок сортировки с помощью ярлыков в Midnight Commander? Как получить доступ к экрану, созданному другими пользователями? Удаление паролей из журналов терминалов в CentOS 7 как команда «init» и «service» может пересекать жизнь обычного пользователя? Nautilus-script для перемещения файла в один и тот же каталог имен Конвертировать PDF из цветового пространства sRGB в CMYK Как я могу изменить порядок, в котором база данных update-desktop помещает приложения, поддерживающие mimetype? LUKS хранит ключевой файл в зашифрованном USB-накопителе Редактировать вывод inotifywait в режиме демона сортировка вывода ps по времени процессора на linux

Выходной контекст (-C) для grep создает массивные файлы

Задача:

Я использую grep для поиска в некоторых текстовых файлах, передавая результаты из одного grep (исключая несколько строк) в другую (сопоставляя несколько строк) + отображая некоторый контекст, используя параметр -C как показано ниже:

 grep -v "Chapter" *.txt | grep -nE -C1 " leaves? " 

Проблема:

Это работает очень хорошо при печати результатов, но создает очень большие файлы (~ несколько ГБ) и занимает вечно, когда я записываю его в файл следующим образом:

 grep -v "Chapter" *.txt | grep -nE -C1 " leaves? " > out.txt 

Устранение проблем:

  1. grep возвращает только 1345 строк (согласно wc ), распечатка занимает несколько секунд

  2. Вывод в больших выходных файлах выглядит правдоподобно, то есть фактические результаты из входных файлов.

  3. Замена оператора -C на -A или -B приводит к хорошим выходным файлам размером в КБ.

Вопросы:

  • Почему это происходит?
  • Есть ли что-то в -C что так ломает вещи?
  • Или есть другая проблема, которую я пропускаю?

Любые намеки приветствуются! Запуск этого в терминале MacOS. Я следил за этим человеком.

Попробуйте изменить каталог, в который вы пишете out.txt . Например, измените эту команду на эту:

 $ grep -v "Chapter" *.txt | grep -nE -C1 " leaves? " > /tmp/out.txt 

пример

Здесь вы можете увидеть, что происходит, когда вы включаете подробный вывод в вашей оболочке Bash.

 $ set -x $ grep -v "Chapter" *.txt | grep -nE -C1 " leaves? " > out.txt + grep --color=auto -nE -C1 ' leaves? ' + grep --color=auto -v Chapter file01.txt file02.txt file03.txt file04.txt file05.txt file06.txt file07.txt file08.txt file09.txt file10.txt out.txt 

Обратите внимание, что он принимает аргумент *.txt и расширяет его и включает в себя файл out.txt . Таким образом, вы буквально анализируете этот файл, когда пишете в него.

Зачем?

Если вы думаете о том, что делает shell, когда вывод одной команды передается следующей, это имеет смысл. Оболочка анализирует команды, которые вы только что дали, в поисках каналов ( | ). Когда он сталкивается с ними, он должен запускать их справа, чтобы установить redirect STDIN / STDOUT между командами, происходящими в каналах.

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

 $ sleep 0.1 | sleep 0.2 | sleep 0.3 | sleep 0.4 + sleep 0.2 + sleep 0.3 + sleep 0.4 + sleep 0.1 $ sleep 0.1 | sleep 0.2 | sleep 0.3 | sleep 0.4 | sleep 0.5 + sleep 0.2 + sleep 0.3 + sleep 0.4 + sleep 0.5 + sleep 0.1 

Выполнение этого с echo + записью в файл также показывает порядок через доступ к файлу и команду stat :

 $ echo "1" > file1 | echo "2" > file2 | echo "3" > file3 | echo "4" > file4 + echo 2 + echo 3 + echo 4 + echo 1 $ stat file* | grep -E "File|Access: [[:digit:]]+" + grep --color=auto -E 'File|Access: [[:digit:]]+' + stat file1 file2 file3 file4 File: 'file1' Access: 2018-08-11 23:55:20.868220474 -0400 File: 'file2' Access: 2018-08-11 23:55:20.865220576 -0400 File: 'file3' Access: 2018-08-11 23:55:20.866220542 -0400 File: 'file4' Access: 2018-08-11 23:55:20.867220508 -0400