我有以下简单的代码段:
#!/bin/bash
tail -f "data/top.right.log" | while read val1
do
val2=$(tail -n 1 "data/top.left.log")
echo $(echo "$val1 - $val2" | bc)
done
top.left.log
和top.right.log
是其他一些进程不断编写的文件。 bash脚本只是减去两个文件的最后几行并显示结果。
我想让脚本更有效率。在伪代码中,我想这样做:
#!/bin/bash
magiccommand "data/top.right.log" "data/top.left.log" | while read val1 val2
do
echo $(echo "$val1 - $val2" | bc)
done
这样每当top.left.log
OR top.right.log
更改时,都会调用echo命令。
我已经尝试过来自StackOverflow的各种代码片段,但通常它们依赖于文件不会更改的事实,或者两个文件都包含相同数量的行,这不是我的情况。
答案 0 :(得分:1)
创建每次处理文件时触摸的临时文件。如果任何文件比临时文件更新,请再次处理文件。
spring-boot-devtools
一旦脚本被杀死,您可能需要删除临时文件。
如果文件变化很快,您可能会错过一些行。否则,在某处添加#!/bin/bash
log1=top.left.log
log2=top.right.log
tmp=last_change
last_change=0
touch "$tmp"
while : ; do
if [[ $log1 -nt $tmp || $log2 -nt $tmp ]] ; then
touch "$tmp"
x=$(tail -n1 "$log1")
y=$(tail -n1 "$log2")
echo $(( x - y ))
fi
done
会降低CPU使用率。
答案 1 :(得分:1)
如果您有inotify-tools
,可以使用以下命令:
inotifywait -q -e modify file1 file2
说明
inotifywait efficiently waits for changes to files using Linux's inotify(7) interface.
It is suitable for waiting for changes to files from shell scripts.
It can either exit once an event occurs, or continually execute and output events as they occur.
一个例子:
while : ;
do
inotifywait -q -e modify file1 file2
echo `tail -n1 file1`
echo `tail -n1 file2`
done
答案 2 :(得分:1)
不是每次都调用tail
,而是可以打开一次文件描述符并逐行读取。这利用了文件保持打开的事实,read
将始终从文件的下一行读取。
首先,在bash中打开文件,为其分配文件描述符3
和4
exec 3<file1 4<file2
现在,您可以使用read -u <fd>
读取这些文件。结合inotifywait
Dawid's answer,这为您提供了一种逐行读取文件的有效方法:
while :; do
# TODO: add some break condition
# wait until one of the files has changed
inotifywait -q -e modify file1 file2
# read the next line of file1 into val1_new
# if file1 has not changed and there is no new line, read will return with failure
read -u 3 val1_new && val1="$val1_new"
# same for file2
read -u 4 val2_new && val2="$val2_new"
done
您可以通过阅读扩展它,直到您到达最后一行,或解析inotifywait
的输出以检测哪个文件已更改。
答案 3 :(得分:0)
一种可能的方法是解析<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' name='word_to_check' value="ba">
<p id="log"></p>
的输出,并在找到tail -f
模式时显示值的差异。
我想出了这个剧本:
==> <==
该脚本假设两个文件中的值均为整数$ cat test.awk
$0 ~ /==>.*right.*<==/ {var=1}
$0 ~ /==>.*left.*<==/ {var=2}
$1~/[0-9]+/ && var==1 { val1=$1 }
$1~/[0-9]+/ && var==2 { val2=$1 }
val1 != "" && val2 != "" && $1~/[0-9]+/{
print val1-val2
}
。
你可以像这样使用它:
[0-9]+
每当在任何文件中附加值时,都会显示每个文件的最后一个值之间的差异。