#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 🙂 ?