URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5794
[ Назад ]

Исходное сообщение
"Простая задачка на bash."

Отправлено cookie , 10-Окт-06 05:50 
Есть два файла.
В первом файле   4000 строк. (access_log_1)
Во втором файле 50000 строк. (access_log)

Нужно взять последнюю строку из файла access_log_1 и найти первое совпадение в файле access_log. В идеале нужен номер строки, но пока упростим задачу.

=====================================================================================
#!/bin/bash

# получаем последнюю строку из файла access_log_1
# заключаем ее в одинарные кавычки чтобы grep искал строку целиком.
STR_END="\'`tail -1 access_log_1`\'"

# выводим эту строку чтобы убедиться, что строка в кавычках
echo $STR_END

# прочитав man grep находим ключик -F PATTERN is a set of newline-separated strings
cat access_log|grep -F `echo $STR`

=====================================================================================

В результате получаем не строку которую искали а куски из нее с ошибками grep.

grep: [06/Oct/2006:18:46:03: No such file or directory
grep: +0400]: No such file or directory
grep: "GET: No such file or directory
grep: /simple_request.php No such file or directory
grep: HTTP/1.1": No such file or directory
grep: 200: No such file or directory
grep: 206: No such file or directory
grep: "Mozilla/4.0: No such file or directory
grep: (compatible;: No such file or directory
grep: MSIE: No such file or directory
grep: 6.0;: No such file or directory
grep: Windows: No such file or directory
grep: NT: No such file or directory
grep: 5.1;: No such file or directory
grep: SV1)"': No such file or directory


Пожалуйста помогите разобраться!

p.s.
пример строки access_log:
'99.99.100.100 - - [06/Oct/2006:18:46:03 +0400] "GET /simple_request.php HTTP/1.1" 200 206 "http://www.host.ru/index.html" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"'


Содержание

Сообщения в этом обсуждении
"Простая задачка на bash."
Отправлено user , 10-Окт-06 08:37 
>Есть два файла.
>В первом файле   4000 строк. (access_log_1)
>Во втором файле 50000 строк. (access_log)
>
>Нужно взять последнюю строку из файла access_log_1 и найти первое совпадение в
>файле access_log. В идеале нужен номер строки, но пока упростим задачу.
>
>
>=====================================================================================
>#!/bin/bash
>
># получаем последнюю строку из файла access_log_1
># заключаем ее в одинарные кавычки чтобы grep искал строку целиком.
>STR_END="\'`tail -1 access_log_1`\'"
>
># выводим эту строку чтобы убедиться, что строка в кавычках
>echo $STR_END
>
># прочитав man grep находим ключик -F PATTERN is a set of
>newline-separated strings
>cat access_log|grep -F `echo $STR`
>
>=====================================================================================
>
>В результате получаем не строку которую искали а куски из нее с
>ошибками grep.
>
>grep: [06/Oct/2006:18:46:03: No such file or directory
>grep: +0400]: No such file or directory
>grep: "GET: No such file or directory
>grep: /simple_request.php No such file or directory
>grep: HTTP/1.1": No such file or directory
>grep: 200: No such file or directory
>grep: 206: No such file or directory
>grep: "Mozilla/4.0: No such file or directory
>grep: (compatible;: No such file or directory
>grep: MSIE: No such file or directory
>grep: 6.0;: No such file or directory
>grep: Windows: No such file or directory
>grep: NT: No such file or directory
>grep: 5.1;: No such file or directory
>grep: SV1)"': No such file or directory
>
>
>Пожалуйста помогите разобраться!
>
>p.s.
>пример строки access_log:
>'99.99.100.100 - - [06/Oct/2006:18:46:03 +0400] "GET /simple_request.php HTTP/1.1" 200 206 "http://www.host.ru/index.html" "Mozilla/4.0
>(compatible; MSIE 6.0; Windows NT 5.1; SV1)"'


Возможно стоит посмотреть на массивы.
Выглядеть будет приблизительно так.

#!/usr/local/bin/bash

FILE_ONE="/hoem/user/file1"
FILE_TWO="/hoem/user/file2"
ARRAY_ONE=("`less ${FILE_ONE}`")
ARRAY_TWO=("`less ${FILE_TWO}`")

for i in "${ARRAY_ONE}[@]"; do
  for j in "${ARRAY_TWO}[@]"; do
   if "$i" = "$j"; then
     echo "Совпадение найдено";
   else echo "Совпадение отсутствует";
   fi;
done;
done

Можно обхявить третий массив и заводить туда по мере нахождения нужные строки.
Условие: исходные файлы должны иметь в одной строке одно значение.


"Простая задачка на bash."
Отправлено cookie , 10-Окт-06 08:57 
Возможно и стоило бы если файл access_log не был так велик и не рос бы со временем.

Никакой памяти не хватит чтобы обработать файлы в 500 - 600 мегобайт.
Да и производительность будет в 10 раз меньше.

Так что мне кажется нужно копать в сторону grep.

p.s. мне нужно найти в файле access_log последнюю строку файла access_log_1:

STR_END="\'`tail -1 access_log_1`\'"
т.е. второй файл обрабатывать не нужно.

проблема в том что не получается с помощью grep проверить всю строку хотя строка заключена в одинарные кавычки как этого требует grep... после первого пробела возникает ошибка(см 1 пост)!


"Простая задачка на bash."
Отправлено cookie , 10-Окт-06 09:55 
Задача решилась в 1 строку :-)

код:
===============================================================
#!/bin/bash

cat access_log|grep -F -n "`tail -1 access_log_1`"|grep -o -E '^([0-9])+'

Последний grep нужен чтобы получить только номер строки совпадения а не всю совпадшую строку!

Время выполнения при файле access_log в 200 мегобайт <= 1 сек.

Спасибо за участие :-)