我想创建一个脚本来动态调用此 awk 命令:
awk '/2019.07.16 09:00/, /2019.07.16 10:00:/' mylog.log | awk '$3 == "-" && $4 != "-" {print $4}' | sort | uniq | wc -l
我通常会成功调用该命令,但现在我想多次执行它并更改时间范围,我在设置时间时遇到困难,以下是我尝试过的内容:
for counter in {7..7}
do
echo "Counter "$counter
echo /2019.07.16 0"$counter":00/, /2019.07.16 0"$((counter+1))":00:/
# The commented code shows unsuccessful attempts
#awk '/2019.07.16 0"$counter":00/, /2019.07.16 "$((counter+1))":00:/' mylog.log | awk '$3 == "-" && $4 != "-" {print $4}' | sort | uniq | wc -l
# The commented code shows unsuccessful attempts
#startvar=0"$counter":00/,
#echo $startvar
#awk -v start="$startvar" '/2019.07.16 start /2019.07.16 08:00:/' mylog.log | wc -l
done
你有什么提示吗?预先感谢,再见
答案1
当您使用双引号而不是单引号时,变量替换将在引号之间起作用。使用这种方法,您必须将脚本中的所有$
和"
字符引用awk
为\$
或\"
。
awk "/2019.07.16 0$counter:00/, /2019.07.16 0$((counter+1)):00:/" mylog.log | ...
请注意,只有0$counter:00
和的解决方案才有效。0$((counter+1)):00
counter+1 < 10
如果您还想过滤两位数的小时值,可以对小时字符串使用 printf 格式:
start=$(printf "%2.2d" "$counter")
stop=$(printf "%2.2d" "$((counter+1))")
awk "/2019.07.16 $start:00:/, /2019.07.16 $stop:00:/" mylog.log | ...
如果您的实际输入数据每行都包含日期和时间,并且不需要下一小时的 00 分钟,则可以简化该模式:
awk "/2019.07.16 $start:/" mylog.log | ...
例如,应该打印从到 的start=07
所有行。07:00:00
07:59:59
通过这种简化,您还可以将两个awk
脚本合并为一个。
awk "/2019.07.16 $start:/ && \$3 == \"-\" && \$4 != \"-\" {print \$4}" mylog.log | sort -u | wc -l
注意:sort -u
给出与 相同的输出sort | uniq
。
为了更好的解决方案,我需要知道输入数据的确切格式。
假设日期位于第 1 列,时间位于第 2 列,您可以将数据作为awk
变量传递,而无需在脚本代码中进行 shell 变量扩展awk
。该解决方案允许使用单引号并避免代码注入漏洞以及脚本中的引用$
或引用。"
timepattern=$(printf "^%2.2d:" "$counter")
date="2019.07.16"
awk -v date="$date" -v timepattern="$timepattern" '$1 == date && $2 ~ timepattern && $3 == "-" && $4 != "-" {print $4}' mylog.log | sort -u | wc -l