我有一个返回数千行数据的日志,我想从中提取一些值。
在日志中只有一行包含唯一的unit
引用,所以我可以使用以下方法grep:
grep "unit=Central-C152" logfile.txt
这会产生类似于以下内容的输出线:
a3cd23e,85d58f5,53f534abef7e7,unit=Central-C152,locale=32325687-8595-9856-1236-12546975,11="School",1="Mr Green",2="Qual",3="SWE",8="report",5="channel",7="reset",6="velum"
线的格式可能会发生变化,因为值的顺序并不总是在同一位置。
我正在尝试找出如何获得2和7的值来分离变量。我曾经考虑过cut
,或者=但由于这些值不是按照设定的顺序,我无法找到最好的方法。
我想要得到:
var state=value of 2 without quotes
var mode=value of 7 without quotes
任何人都可以建议最好的方法吗?
谢谢
你可以尝试下面创建变量的值。
state=$(awk '/unit=Central-C152/ && match($0,/2=\"[^"]*/){print substr($0,RSTART+3,RLENGTH-3)}' Input_file)
mode=$(awk '/unit=Central-C152/ && match($0,/7=\"[^"]*/){print substr($0,RSTART+3,RLENGTH-3)}' Input_file)
你可以通过以下方式打印它们。
echo "$state"
echo "$mode"
说明:现在也添加命令说明。
awk ' ##Starting awk program here.
/unit=Central-C152/ && match($0,/2=\"[^"]*/){ ##Checking condition if a line has string (unit=Central-C152) and using match using REGEX to check from 2 to till "
print substr($0,RSTART+3,RLENGTH-3) ##Printing substring starting from RSTART+3 till RLENGTH-3 characters.
}
' Input_file ##Mentioning Input_file name here.
假设你已经在一个变量中有这样的行,例如:
line="$(grep 'unit=Central-C152' logfile.txt | head -1)"
然后,您可以简单地使用bash
的内置参数替换功能:
f2=${line#*2=\"} ; f2=${f2%%\"*} ; echo ${f2}
f7=${line#*7=\"} ; f7=${f7%%\"*} ; echo ${f7}
每条线上的第一个命令剥离线的第一部分,包括<field-number>="
。然后第二个命令将除了(包括)第一个引用之外的所有内容删除。第三,当然,简单地回应价值。
当我针对您的输入行运行这些命令时,我看到:
Qual
reset
从我所看到的,你所追求的是什么。
你可能最好在Awk中完成所有处理。
awk -F, '/unit=Central-C152/ {
for(i=1;i<=NF;++i)
if($i ~ /^[27]="/) {
b[++k] = $i
sub(/^[27]="/, "", b[k])
sub(/"$/, "", b[k])
gsub(/\\/, "", b[k])
}
print "state " b[1] ", mode " b[2]
}' logfile.txt
这预示着字段总是以相同的顺序出现(在7之前的2)。也许您需要更改或禁用gsub
以删除值中的反斜杠。
如果你想做的不仅仅是打印值,那么重构你在Awk中的任何Bash代码通常比在Bash中进行这种处理更好。