使用awk关闭文件并执行一组命令

时间:2017-02-22 20:21:14

标签: linux shell awk tail

我想在日志文件上运行tail,并在该日志文件中的字符串匹配后执行一组命令。在执行结束时,tail命令应该退出。

我的尝试如下所示。似乎文件中找到的任何字符串都会导致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") } '

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

@MRE:尝试:(我认为我们不需要提到这么多系统调用,尽管我还没有测试过它。)

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

请尝试一次,让我们知道它是如何进行的。

答案 1 :(得分: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选项.1 USG风格的grep也缺少-q但是它的-s选项   表现得像GNU grep的。便携式shell脚本应该避免-q   和-s并应将标准和错误输出重定向到/ dev / null   代替。 (-s由POSIX指定。)

例如

假设这是日志

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

for true

$ 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

答案 2 :(得分: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") }'