Как найти шаблон и окружающее содержимое в очень большом однострочном файле?

#parsing #bash

#синтаксический анализ #bash

Вопрос:

У меня очень большой файл 100 МБ , где все содержимое находится в одной строке. Я хочу найти шаблон в этом файле и количество символов вокруг этого шаблона.

Например, я хотел бы вызвать команду, подобную приведенной ниже, но где -A и -B — это количество байтов, а не строк:

 cat very_large_file | grep -A 100 -B 100 somepattern
  

Итак, для файла, содержащего содержимое, подобное этому:

 1234567890abcdefghijklmnopqrstuvwxyz
  

С шаблоном

 890abc
and a before size of -B 3 
and an after size of -A 3
  

Я хочу, чтобы он возвращал:

 567890abcdef
  

Любые советы были бы замечательными.
Большое спасибо.

Ответ №1:

Вы можете попробовать опцию -o:

 -o, --only-matching
      Show only the part of a matching line that matches PATTERN.
  

и используйте регулярное выражение, чтобы соответствовать вашему шаблону и 3 предыдущим / следующим символам, т.е.

 grep -o -P ".{3}pattern.{3}" very_large_file 
  

В приведенном вами примере это будет

 echo "1234567890abcdefghijklmnopqrstuvwxyz" > tmp.txt
grep -o -P ".{3}890abc.{3}" tmp.txt
  

Комментарии:

1. Извините, правильный вариант для регулярных выражений — P, а не -e

Ответ №2:

Еще один с sed (он может понадобиться в системах, где GNU grep недоступен):

 sed -n '
  s/.*(...890abc...).*/1/p
  ' infile
  

Ответ №3:

Лучший способ, который я могу придумать, сделать это с помощью крошечного скрипта Perl.

 #!/usr/bin/perl
$pattern = $ARGV[0];
$before = $ARGV[1];
$after = $ARGV[2];

while(<>) {
  print $amp; if( /.{$before}$pattern.{$after}/ );
}
  

Затем вы должны выполнить его таким образом:

 cat very_large_file | ./myPerlScript.pl 890abc 3 3
  

РЕДАКТИРОВАТЬ: Черт возьми, решение Паоло намного проще. Ну что ж, да здравствует Perl!

Комментарии:

1. Ну, когда кто-то думает о регулярных выражениях, Perl является своего рода родным языком… угадайте, что означает -P в моей строке grep 🙂 ?