2015-07-09 4 views
-1

Я хочу grep для слова в файле в последних n строках без использования трубы.Grep для строки в файле без использования трубы

grep <string> filename 

позволяет искать имя файла для строки. Но я хочу найти строку в последних N строках файла. Любая команда для поиска этого без использования трубы?

+3

Почему вы избегаете труб? IPC является основой философии UNIX, которая не сводит на нет все функциональные возможности в монолитные программы и вместо этого связывает небольшие специализированные программы. – PSkocik

+4

Как насчет 'tail -50 filename> filename2 && grep filename2'? Нет труб и последних 50 строк. – zedfoxus

+2

LOL, очень хорошо. Другая идея - 'sed -n '$ n, \ $/srchTarg/p" file'. где $ n поставил бы, чтобы установить первую строку выражения диапазона для поиска. Удачи. – shellter

ответ

3

Использование процесса Замена для поиска строки только в последние 5 строк:

grep string <(tail -n 5 filename) 
+2

Увы, замена процесса реализована в оболочке как трубы. Здесь нужна чистота !!! – msw

1

Использование PERL Oneliner:

perl -0777 -wlnE 'my @all = split("\n",$_); my $t = scalar @all; for my $l(@all[$t-50 .. $t]) {print $l if $l =~ /word/;} filename' 
+0

Что с большим slurp? Решение 'sed', размещенное в комментарии от shellter, делает это намного элегантнее. Вы можете использовать одну и ту же логику в Perl, если хотите, и рассчитываете значение 'n'. – tripleee

2

Off верхней части моей головы, командная оболочка:

ed input <<EOF 
$ 
1,-50d 
v/pattern/d 
w output 
q 
EOF 

будет работать. С дополнительным преимуществом, что показания об ошибках - только один символ ? для краткости. Конечно, вам нужно будет изменить документ ЗДЕСЬ в зависимости от того, сколько хвостов вы хотите (-50), шаблон и имена входных и выходных файлов при каждом изменении ваших аргументов. И вам нужно иметь машину, которая все еще работает ed, но по крайней мере вам не придется использовать трубу.

2

Вот простой сценарий Awk, который находит все совпадения, но в конечном итоге печатает только те, которые находятся в пределах 50 строк от конца файла.

awk -v pattern='foo' -v limit=50 '$0 ~ pattern { a[NR]=$0 } 
    END { for (n in a) if (n >= NR-limit) print a[n] }' file 

Массив a хранит каждый матч с его номером строки в качестве ключа; в цикле END мы печатаем элементы массива, чей ключ находится в пределах лимита.