2013-02-14 4 views
16

У меня есть проблема с командой grep.получить последнюю строку из поиска grep по нескольким файлам

Я нашел способ показать только последнюю строку поиска Grep:

grep PATERN FILE_NAME | tail -1 

Я также найти способ сделать поиск Grep в нескольких выбранных файлов:

find . -name "FILE_NAME" | xargs -I name grep PATERN name 

Теперь я хотел бы получить только последнюю строку результата grep для каждого отдельного файла. Я попытался это:

find . -name "FILE_NAME" | xargs -I name grep PATERN name | tail -1 

Это возвращает мне только последнее значение последнего файла, в котором я хотел бы иметь последний соответствующий Patern для каждого файла.

ответ

25
for f in $(find . -name "FILE_NAME"); do grep PATERN $f | tail -1; done 
+0

отлично работает! Спасибо! : D –

+0

К сожалению, это не будет эффективно для огромных файлов или сложных поисков шаблонов, если вы ищете весь файл и возвращаете только последний результат? Как о чем-то вроде следующего, в вашем цикле for: 'tac file | grep -m1 -oP '(? <=tag>). * (?=) '| head -n 1' или даже 'grep -m1 -oP '(? <=tag>). * (? =)' << (tac-файл)' – kisna

2

Как об этом сударь

find . -name "FILE_NAME" -print0 | while read -d '' aa 
do 
    grep PATTERN "$aa" | tail -1 
done 
+0

такой же дух, что и первый комментарий, отлично работает! –

0

вы можете использовать поиск для выполнения команд тоже:

find . -name "<file-name-to-find>" -exec grep "<pattern-to-match>" "{}" ";" | tail -1 

«{}» это имя файла, позаботьтесь с globing оболочки и expasion при написании команда

-1

Существует решение, не требующее циклов, это дает то, что хочет OP.

find . -type f -exec sh -c "fgrep print {} /dev/null |tail -1" \; 

./tway.pl:print map(lambda x : x[1], filter(lambda x : x[0].startswith('volume'), globals().items())) 
./txml.py:   print("%s does not exist: %s\n" % (host, error)) 
./utils.py:print combine_dicts(a, b, operator.mul) 
./xml_example.py:print ET.tostring(root, method="text") 

По сравнению без tail -1 дает Слишком много строк на файл, но доказывает вышеуказанные работы.

find . -type f -exec sh -c "fgrep print {} /dev/null" \; 

дает:

./tway.pl:print map(lambda x : x[1], filter(lambda x : x[0].startswith('volume'), globals().items())) 
./txml.py:   print("%s resolved to --> %s\n" % (host, ip)) 
./txml.py:   print("%s does not exist: %s\n" % (host, error)) 
./utils.py:print "a", a 
./utils.py:print "b", b 
./utils.py:print combine_dicts(a, b, operator.mul) 
./xml_example.py: print ">>" 
./xml_example.py: print ET.tostring(e, method="text") 
./xml_example.py: print "<<" 
./xml_example.py:print ET.tostring(root, method="text") 

EDIT - удалить/DEV/нулевое значение, если вы не хотите, чтобы имя файла включена в вывод.

-2

Самый быстрый способ сделать это - получить выходные последние 1 (или более) строки из файлов, а затем grep через это. Так что -

tail -1 filenames.* | grep "what you want to grep for" 
+2

Последняя строка не обязательно соответствует шаблону, так что это не показать последнее соответствие для файла. –

-1

Другой способ найти последней линии заключается в обратном файл и вывести первый матч.

find . -name "FILE_NAME" | xargs -I name sh -c 'tac name|sed -n "/PATTERN/{p;q}"' 
0

Вы можете начать с параметра grep -B (before). Например, чтобы получить 5 строк до начала матча:

[email protected] /etc/php5/apache2 $ grep -i -B5 timezone php.ini 
[CLI Server] 
; Whether the CLI web server uses ANSI color coding in its terminal output. 
cli_server.color = On 

[Date] 
; Defines the default timezone used by the date functions 
; http://php.net/date.timezone 
;date.timezone =