Bash 将Awk的输出包含到变量中并将其与整数进行比较
我花了90分钟在谷歌上搜索这个问题,所以我希望我没有问一个以前被问过好几次的问题 我目前正试图解析一个日志文件,需要一行中的特定值。 文本文件内容:Bash 将Awk的输出包含到变量中并将其与整数进行比较,bash,awk,comparison,Bash,Awk,Comparison,我花了90分钟在谷歌上搜索这个问题,所以我希望我没有问一个以前被问过好几次的问题 我目前正试图解析一个日志文件,需要一行中的特定值。 文本文件内容: read: 4163419415 0 0 4163419415 0 4395.007 0 read: 4163419415 0 0 4163419415 0 4395.007 0 read: 4163419415 0 0 4
read: 4163419415 0 0 4163419415 0 4395.007 0
read: 4163419415 0 0 4163419415 0 4395.007 0
read: 4163419415 0 0 4163419415 0 4395.007 1
read: 4163419415 0 0 4163419415 0 4395.007 0
我需要获取最后一个值(可以是变量)并对其进行一些检查
COUNTER=1
while [ $COUNTER -lt 26 ]; do
ECREAD=$(awk '/read:/{i++}i=='$COUNTER'{print $8; exit}' ./txt.file)
echo $ECREAD
if [ "$ECREAD" > 0 ]
then
echo "fail"
fi
let COUNTER=COUNTER+1
done
我的问题是,无论$ECREAD的值是多少,if语句总是正确的。
我试过了
[[ $ECREAD =~ ^-?[0-9]+$ ]] && echo integer
验证变量是否为整数
我还尝试通过将命令的awk部分管道化到sed的/*$/'
和sed的/^*/'
和tr-d'
我已尝试将IF语句周围的[]改为[[]]
和(())
我已尝试将
符号更改为-gt
符号。回答修改后的问题
假设我们有inputfile
。我们只想检查前24行。如果其中任何一行以read:
开头,并且最后一列大于零,则我们希望打印Fail
如果是这样,那么:
$ awk '/^read:/ && $NF > 0 {print "Fail";} NR>=24{exit;}' inputfile
Fail
工作原理
对于以/^read://&&$NF>0{打印“失败”}
开头且其最后一列read:
大于零的任何行,则打印$NF
Fail
NR>=24{exit;}
提供一个名为awk
的记录(行)计数器。处理第24行后,程序将退出,不再进一步读取NR
bash
循环的备选方案
如果目标是在bash循环中一次使用一行awk,那么请尝试:
for ((counter=1; counter<26; counter++))
do
ecread=$(awk -v num=$counter '/read:/ && NR==num {print $8} NR==num{exit;}' ./txt.file)
echo ecread=$ecread
if [ "$ecread" ] && [ "$ecread" -gt 0 ]
then
echo "fail"
fi
done
笔记
/read:///code>与任何内容都不匹配。输入,至少如问题中所示,在
和read
之间有一个空格。因此,测试更改为:
/read://
- 代码
的用途不清楚,已将其删除{i++}o==$COUNTER'
- 样本输入中的
值是一个浮点:4395.007。shell只执行整数运算。但是,ECREAD
可以很好地处理浮动。因此,测试转换为使用bc
bc
- 与shell测试命令比较时,
,符号[
和赋值行有点乱:
有三个单引号,没有反斜杠,这会带来麻烦。您可能需要:ECREAD=$(awk '/read:/{i++}o==$COUNTER'{print $8; exit}' ./txt.file)
这在语法上是有效的。不清楚它是否达到了预期效果。如果模式匹配(与示例数据不匹配),则变量ECREAD=$(awk '/read:/ {i++} o==$COUNTER {print $8; exit}' ./txt.file)
将递增,但在其他方面未使用。测试i
将未设置的变量o=$COUNTER
与o
进行比较(因为$0
是一个未设置的变量,因此计算结果为0)。由于条件为非真,因此不会执行打印。这可能会达到您的目的:计数器
您的shell“ECREAD=$(awk '/^read :/ { print $8; exit}' ./txt.file)
”语句非常混乱: 应该是:if
或:if [ "$ECREAD" -gt 0 ] then echo "fail" fi
你可以试试类似的东西$ ECREAD=$(awk '$1~/read/{print $7}' input ) $ if [ $ECREAD -gt 0 ] > then > echo fail > else > echo pass > fi pass
在这里,纯bash解决方案与使用awk
解析文件一样简单,它能够读取read
、空格
或选项卡
分隔文本(默认值:内部字段分隔符换行符
)不更改分隔符。然后您可以将前七个值读入垃圾变量并丢弃,只留下您感兴趣的$IFS
值ecread
解决方案也很好,但如果您在bash中工作,它也可以满足您的需要,而无需依赖外部流程:awk
#!/bin/bash ## accept filename as first argument to script (default dat/ecread.dat) fn="${1:-dat/ecread.dat}" ## validate file is readable [ -r "$fn" ] || { printf "error: file not readable '%s'. Usage: %s <filename> (dat/ecread.dat)\n\n" "$fn" "${0//*\//}" exit 1 } declare -i counter=1 # declare counter as int, set to 1 ## read each line in data-file and discard first 7 values (while counter < 26) while [ "$counter" -lt 26 ] && read a a a a a a a ecread || [ -n "$ecread" ]; do printf " ecread: %s" "$ecread" ## test ecread > 0, if so fail, if not OK [ "$ecread" -gt 0 ] && printf " -- fail\n" || printf " -- OK\n" counter+=1 done <"$fn" exit 0
我最好的猜测是,
是一些COUNTER
变量&看看不匹配的单引号,OP的意思可能是:bash
@anishsane:可能是这样,但因为$(awk'/read:/{i++}o=='$COUNTER'{print$8;exit}./txt.file)
未初始化(0或空字符串),并且从未设置,除非o
也为0(空字符串不起作用)。@JonathanLeffler I aplogize,但这是该行应该显示的$COUNTER
未完成意外输入抱歉。@John1024感谢您的帮助,但我仍然有问题,我也为这样一个草率的问题道歉。您的假设是正确的,我错误地输入了“示例测试”部分。应该是:读:2553734844 0 0 2553734844 0 4386.350 0,这样就不需要浮点。@John1024 Comment continued在编辑时被5分钟规则击中,试图使用这些论坛。当我使用你的代码片段时,它工作得很好,但当我在计数器中添加时,我遇到了错误:整数表达式e预期我会有不止一个“读:”(~24)row所以我认为我需要计数器。所以我认为问题在于我如何实现计数器。其他用户所做的所有更正都是正确的。我已在OP中添加了更多信息。我认为我试图过于模糊和基本,有点遗漏了一些重要的细节,我道歉。请查看我修改后的答案,并告知它是否捕获了错误所有详细信息。ECREAD=$(awk'/read:/{I++}I='$COUNTER'{print$8;exit}./txt.file)
我需要计数器,因为有多次迭代,我相信计数器出于某种原因导致了问题。ECREAD=$(awk'/read:/{i++}i='$COUNTER'{print$8;exit}./txt.file)
ECREAD=$(awk '/read:/ {i++} o==$COUNTER {print $8; exit}' ./txt.file)
ECREAD=$(awk '/^read :/ { print $8; exit}' ./txt.file)
[ if "$ECREAD" > 0 ] then echo "fail" fi
if [ "$ECREAD" -gt 0 ] then echo "fail" fi
if [[ "$ECREAD" -gt 0 ]] then echo "fail" fi
$ ECREAD=$(awk '$1~/read/{print $7}' input ) $ if [ $ECREAD -gt 0 ] > then > echo fail > else > echo pass > fi pass
#!/bin/bash ## accept filename as first argument to script (default dat/ecread.dat) fn="${1:-dat/ecread.dat}" ## validate file is readable [ -r "$fn" ] || { printf "error: file not readable '%s'. Usage: %s <filename> (dat/ecread.dat)\n\n" "$fn" "${0//*\//}" exit 1 } declare -i counter=1 # declare counter as int, set to 1 ## read each line in data-file and discard first 7 values (while counter < 26) while [ "$counter" -lt 26 ] && read a a a a a a a ecread || [ -n "$ecread" ]; do printf " ecread: %s" "$ecread" ## test ecread > 0, if so fail, if not OK [ "$ecread" -gt 0 ] && printf " -- fail\n" || printf " -- OK\n" counter+=1 done <"$fn" exit 0
$ bash ecread.sh ecread: 0 -- OK ecread: 0 -- OK ecread: 1 -- fail ecread: 0 -- OK