问题:比较特定参数的节点的预检查状态和检查后状态的文件。
在社区的帮助下,我编写了以下解决方案,该解决方案从前后目录中的文件中提取信息,并基于“节点ID”(恰好是唯一的,并从文件中提取为好)。从Pre / post文件夹中提取数据后,我已根据node-id和转储文件将文件夹创建到文件夹中。
我的代码提取数据(数据从Pre和Post文件夹中提取)
FILES=$(find postcheck_logs -type f -name *.log)
for f in $FILES
do
NODE=`cat $f | grep -m 1 ">" | awk '{print $1}' | sed 's/[>]//g'` ##Generate the node-id
echo "Extracting Post check information for " $NODE
mkdir temp/$NODE-post ## create a temp directory
cat $f | awk 'BEGIN { RS=$NODE"> "; } /^param1/ { foo=RS $0; } END { print foo ; }' > temp/$NODE-post/param1.txt ## extract data
cat $f | awk 'BEGIN { RS=$NODE"> "; } /^param2/ { foo=RS $0; } END { print foo ; }' > temp/$NODE-post/param2.txt
cat $f | awk 'BEGIN { RS=$NODE"> "; } /^param3/ { foo=RS $0; } END { print foo ; }' > temp/$NODE-post/param3.txt
done
在此之后,我有一个结构:
/Node1-pre/param1.txt
/Node1-post/param1.txt
等等。
现在我很难比较$NODE-pre
和$NODE-post
个文件,
我尝试使用递归grep来做,但我找不到合适的方法。使用diff?
比较这些文件的最佳方法是什么?而且,我发现上面的数据提取程序非常慢。我认为这不是最好的方式(使用最少的资源)。有什么建议吗?
答案 0 :(得分:3)
请注意cat one-file
的任何实例 - 您可以在管道中的下一个命令上使用I / O重定向。
你可以更简单地完成整个事情:
for f in $(find postcheck_logs -type f -name *.log)
do
NODE=$(sed '/>/{ s/ .*//; s/>//g; p; q; }' $f) ##Generate the node-id
echo "Extracting Post check information for $NODE"
mkdir temp/$NODE-post
awk -v NODE="$NODE" -v DIR="temp/$NODE-post" \
'BEGIN { RS=NODE"> " }
/^param1/ { param1 = $0 }
/^param2/ { param2 = $0 }
/^param3/ { param3 = $0 }
END {
print RS param1 > DIR "/param1.txt"
print RS param2 > DIR "/param2.txt"
print RS param3 > DIR "/param3.txt"
}' $f
done
单个sed
命令比cat | grep | awk | sed
更好地完成NODE查找过程,您应该计划在任何地方使用$(...)
而不是后引号。
日志文件的主要处理应该进行一次;单个awk
命令就足够了。该脚本将传递给变量 - NODE和目录名称。 BEGIN被清理干净; NODE之前的$
可能不是你想要的。主要行动非常相似;每个都查找相关的参数名称并将其保存在适当的变量中。最后,它将保存的值写入相关文件,用RS的值进行修饰。只有在一行上有多个语句时才需要分号;在这个扩展的脚本中,每行只有一个语句。它看起来比原来大,但这只是因为我使用垂直空间。
至于比较之前和之后的文件,您可以通过多种方式进行,具体取决于您想知道的内容。如果你有一个符合POSIX的diff
(你可能会这样做),你可以使用:
diff -r temp/$NODE-pre temp/$NODE-post
报告两个目录内容之间的差异(如果有)。或者,您可以手动执行此操作:
for file in param1.txt param2.txt param3.txt
do
if cmp -s temp/$NODE-pre/$file temp/$NODE-post/$file
then : No difference
else diff temp/$NODE-pre/$file temp/$NODE-post/$file
fi
done
显然,你可以将它包装在'for each node'循环中。而且,如果您需要这样做,那么您可能希望在变量中捕获find
命令的输出(如在原始代码中),这样您就不必重复该操作。