以下命令没有给出任何结果。我想grep
从文件中提取错误行并将其插入表中。
不起作用的命令:
tail -f logfile.log | grep ERROR|while read msg; do psql -d testdb -c insert into t values('$msg'); done
但如果我grep ERROR
从命令中删除代码,它就会按预期工作。我不知道发生了什么事?
运行良好的命令:
tail -f logfile.log|while read msg; do psql -d testdb -c insert into t values('$msg'); done
您可以假设文件中有以下数据:
ERROR
sql committed
ERROR
ERROR
error
...
答案1
两件事情:
正如问题中所写的,代码将插入文字字符串
$msg
(如果它有效的话),因为您在它周围使用了单引号。请改用双引号。在这里,我将整个语句放在双引号中,这将扩展内部$msg
。 shell 代码仍然很脆弱,具体取决于grep
.理想情况下,应正确清理in 中的字符串,$msg
以便单个'
或其他特殊字符不会破坏语句(或更糟糕的是,请参阅来自用户的评论CAS以下)。tail -f logfile.log | grep -F 'ERROR' | while read msg; do psql -d testdb -c "insert into t values('$msg')" done
当我们使用固定字符串进行搜索时,我还添加了
-F
调用(这主要用于文档目的)。grep
grep
缓冲其输出,因此在其输出缓冲区已满之前不会产生任何内容。这给人的印象是它“不起作用”,而实际上它确实起作用,但它不会执行任何操作,直到grep
刷新其输出缓冲区,一旦有足够的数据,它就会执行此操作。这是一个性能优化。GNU
grep
(以及同一实用程序的一些其他实现,例如 OpenBSD)可以通过其--line-buffered
选项进行行缓冲:tail -f logfile.log | grep --line-buffered -F 'ERROR' | while read msg; do psql -d testdb -c "insert into t values('$msg')" done
注意:我还没有测试过这个,因为我目前没有运行 PostgreSQL (?) 实例。