2017-02-22 50 views
0

Я хотел бы запустить tail в файле журнала и выполнить набор команд, если есть соответствие для строки в этом файле журнала. В конце выполнения команда tail должна выйти.Хвост файла и выполнение набора команд с помощью awk

Моя попытка показана ниже. Кажется, что любая строка, найденная в файле, вызывает вывод tail. Если есть совпадение, набор команд будет запущен, и tail выйдет, как ожидалось.

Почему tail уходит, даже если нет совпадения?

Это моя команда:

tail -f /logs/logfile.log | awk '/string_to_match/ { system("cp /s1/* /d1") } 
                {system("cp /s2/* /d2") } 
                { system("cp /s3/* /d3") }  
                { system("pkill tail") } ' 

Спасибо за вашу помощь.

+1

Способ записи вашего awk, второй, третий, четвертый блоки действий (последняя команда 'kill') будет выполнена для каждой строки ввода, есть ли совпадение или нет. – jas

+0

'/ string_to_match /' применяется только к '{system (" cp/s1/*/d1 ")}' Все остальные действия выполняются для каждой строки канала, включая '{system (" pkill tail ")} ' – dawg

+0

awk предназначен для манипулирования текстом, не пытайтесь использовать его как оболочку - это просто ужасная идея. См. Http://stackoverflow.com/a/42406230/1745001 за разумный подход. –

ответ

0

Способ записи вашего awk, второй, третий, четвертый блоки действий (последняя команда kill) будут выполняться для каждой строки ввода, есть ли совпадение или нет.

Предполагая, что все команды должны выполняться на основе соответствия строки-к-одному, это звучит, как вы хотите вместо этого:

tail -f /logs/logfile.log | awk '/string_to_match/ {system("cp /s1/* /d1") 
                system("cp /s2/* /d2") 
                system("cp /s3/* /d3")  
                system("pkill tail") }' 
2

@MRE: Try: (Нам не нужно упомянуть так много системы звонит, я думаю, хотя я его вообще не тестировал).

tail -f /logs/logfile.log | 
awk '/string_to_match/ { 
      system("cp /s1/* /d1; cp /s2/* /d2; cp /s3/* /d3; pkill tail") }' 

Пожалуйста, попробуйте еще раз и сообщите нам, как это происходит.

+0

Хороший вопрос о том, чтобы делать все с помощью одного системного вызова. – jas

1

Вы не должны использовать awk в текущем контексте,

grep -qs 'string_to_match' logs/logfile.txt && { 
    cp /s1/* /d1; cp /s2/* /d2; cp /s3/* /d3; pkill tail; 
} 

В вашем случае

tail -f logs/logfile.txt | grep -qs 'string_to_match' - && { 
    cp /s1/* /d1; cp /s2/* /d2; cp /s3/* /d3; 
} 

pkill tail; не требуется, поскольку grep -q выходит после первого матча

Попробуйте

В одной из вкладок

for i in {1..15}; do echo $i >> a; sleep 1; done 

В другой вкладке

tail -f a | grep -sq '3' && { echo found; echo done; } 

От Человека

-q

--quiet

--silent

Тихий; не пишите ничего на стандартный вывод. Выйдите немедленно с нулевым статусом, если найдено совпадение, даже если обнаружена ошибка. Также см. Параметр -s или --no-messages. (-q указан POSIX.)

-s

--no-messages

сообщения об ошибках Подавить о несуществующих или нечитаемых файлов. Заметка о переносимости: в отличие от GNU grep, 7-е издание Unix grep не соответствовал POSIX, потому что ему не хватало -q и его опция -s вела себя как GNU grep -q option.1 В графе greg также не было -q, но его -s опция вела себя как GNU grep's. Переносимые сценарии оболочки должны избегать как -q , так и -s и должны перенаправлять стандартный и вывод ошибок на/dev/null . (-s задается POSIX.)

Например

Предположим, что это войти

$ cat logfile 
1 
2 
3 
4 
somestring 
a 
a 
s 
a 

для истинных

$ grep -qs 'somestring' logfile && { echo 'This'; echo 'test'; echo 'done, string found'; } || echo 'not found' 
This 
test 
done, string found 

для ложного

$ grep -qs 'test' logfile && { echo 'This'; echo 'test'; echo 'done, string found'; } || echo 'not found' 
not found