Intereting Posts
ошибка при компиляции ffmpeg: gcc не может создать исполняемый файл Запуск сценария sh: «Permission denied», несмотря на исполняемый бит и права root IFS null – это не то же самое, что unset IFS? rpcbind / nfs не удалось, не удалось создать слушателей RPC, выйти Как заставить текстовую консоль Fedora 28 устанавливать под KVM, чтобы не запрашивать текстовый режим против VNC Соединение VNC занимает много времени, чтобы подключиться (по существу … никогда) Дженкинс за Nginx в Куберне Как использовать sed и регулярные выражения, чтобы найти шаблон и удалить последние несколько символов? Запретить закрытие окна / окна при завершении команды – tmux поведение dd, запись по умолчанию и разделы Arch Linux Gnome 3 медленный вход -> переход на рабочий стол и 2 сеанса gnome при загрузке Подключение через telnet и выполнение определенных операций Как я могу «сбросить» способности? FC20 – удаленный рабочий стол для хоста QEMU Отключить фестиваль от «замещающих» сокращений, отредактировав .festivalrc

распечатать все совпадения или заменить все строки в BIG-файле, который не является строковым (без разделителей строк)

У 5GB-файлов у меня есть потоки строк данных:

{datarow1...},{datarow2...},...,{datarowN...} 

так что на самом деле можно сказать, что существуют строки {} и даже разделители строк, но в виде трехсимвольной последовательности: },{

Я хочу сделать две вещи:

  1. напечатайте « lines », в которых есть строка "error" :

     grep -o -P {[^{}]+?error.+?} ES01.log > ES01.err.log 
  2. сделать файл более «дружественным», явно создавая файлы с новыми разделителями строк

     <ES01.log sed -e 's/},{/}\n{/g' > ESnl01.log 

Хотя это работает для относительно небольших файлов (до ~ 100 Мбайт), мои файлы, к сожалению, намного больше, поэтому проблемы с памятью здесь:

  grep: memory exhausted sed: couldn't re-allocate memory 

так как grep и sed пытаются читать / обрабатывать файлы по строкам, которые в этом случае (без разделителей) приводят к загрузке целых файлов в память.

Любая идея, как подойти к этому, используя какой-то другой смарт-лайнер?

С gawk :

 gawk -v 'RS=},{' '{sub(",", "\n", RT); printf "%s", $0 RT}' < file 

perl-эквивалент:

 perl -pe 'BEGIN{$/="},{"}; s/\,{$/\n{/' < file 

В противном случае POSIXly:

 tr , '\n' < file | awk '{ if (/^{/ && e) print "" printf "%s", $0 if (/}$/) e=1 else {e=0; printf ","}} END {print ""}' 

paste -sd, - с grep error чтобы увидеть записи с ошибками и paste -sd, - восстановить исходный формат.

Вы также можете сделать это в Perl:

 perl -ne 'BEGIN{$/="},{"} chomp; s/\n$//; s/^{//; s/}$//; print "{$_}\n"; ' k 

Это тот же принцип, что и gawk , предложенный StephaneChazelas, в Perl $/ является разделителем записей, поэтому мы устанавливаем это на },{ чтобы правильно читать записи, а затем печатать их с символами новой строки.

Вы можете легко расширить это, чтобы выполнить обе операции, которые вы просите:

 perl -i -ne 'BEGIN{$/="},{"} chomp; s/\n$//; s/^{//; s/}$//; print "{$_}\n"; print STDERR "{$_}\n" if /error/' file 2> ES01.err.log 

Если вы хотите попробовать программу, которая, вероятно, еще не установлена ​​в вашей системе, попробуйте gsar , объясненный в этом ответе на ту же проблему.

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

Эта команда:

 gsar '-s},{' '-r}:x0A{' ES01.log > ESnl01.log 

заменяет запятую между }{ символом новой строки, считая из ES01.log и перенаправляя вывод в ESnl01.log.

Строки поиска ( -s ) и замены ( -r ) не имеют одинаковой длины.

Вы можете сделать это просто через Perl, используя регулярное выражение.

 perl -pe 's/(?<=}),(?=\{)/\n/g' file