我有一个 bash 脚本,其中包含一组数据库名称,连接到每个数据库名称并对其运行存储过程。我需要从存储过程的输出中获取值并在脚本的其余部分使用它们。许多输出都是这样的:
CONDBAT= 10000 MDBAT= 400 ADBAT= 143 QUEDBAT= 167924 INADBAT= 0
然后我注意到一些数据库有不同的输出,没有空格:
CONDBAT=4000 MDBAT=1200 ADBAT=263 QUEDBAT=7924 INADBAT=0
我需要获取 QUEDBAT 之后的值并将其存储为变量。我的问题是我无法获得两个输出的值。我尝试了很多命令。例如:
grep -Eo 'QUEDBAT=([[:space:]]+[^[:space:]]+){1}'
grep -vE -e 'QUEDBAT=[[:space:]]{4}' -e '^[^[:space:]]*$'
grep -oP '(?<=QUEDBAT\=)(\s+)?\K([^ ]*)'
但它们不会返回两个输出的值。如何在 QUEDBAT 忽略任何空格后获取值?
我无法编写单独的脚本,因为我需要一个脚本中所有数据库的所有输出。每次我运行存储过程时,值都会发生变化,因此您无法确定每个部分的值将具有 3 或 4 位数字。而且我也无法得到=
和之间的内容,ADBAT
因为有时输出的顺序会不相同。
答案1
+
是一个或多个。你*
需要零个或多个:
grep -Po '\bQUEDBAT=\s*\K\d+'
或者:
pcregrep -o1 '\bQUEDBAT=\s*(\d+)'
或者使用真实的东西(上面的P
/代表)以实现可移植性:p
perl
perl -lne 'print $1 while /\bQUEDBAT=\s*(\d+)/g'
perl -lne 'print for /\bQUEDBAT=\s*(\d+)/g'
(或者编写整个脚本,perl
如果主要与文本处理有关,则可能更合适)。
答案2
每当您的输入具有 tag=value 对时,我发现最好首先创建一个数组来保存f[]
下面的这些映射 ( ),然后您可以按任何输入顺序获取您喜欢的值,比较它们,重新排序它们等等。只是他们的标签。在每个 Unix 机器上的任何 shell 中使用任何 awk 都可以满足您的具体要求:
$ awk -F'[= ]+' '{for (i=1; i<NF; i+=2) f[$i]=$(i+1); print f["QUEDBAT"]}' file
167924
但是通过使用这种首先构建标签值数组的方法,您可以做更多的事情,例如:
$ awk -F'[= ]+' '
{ for (i=1; i<NF; i+=2) f[$i]=$(i+1) }
(f["QUEDBAT"] > 500) && (f["MDBAT"] < f["CONDBAT"]) {
print f["INADBAT"], f["ADBAT"]
}
' file
0 143
答案3
tr+ sed
管道可以用在我们在线“=”分隔字段的地方。
< file tr -s ' =' '\n' |
sed -n '/^QUEDBAT$/{n;p;}'
GNU sed
也可以单独使用。
sed -E '
s/(^|\s)QUEDBAT=\s*(\S+)/\n\2\n/
s/.*\n//M;/\n/P;D
' file
结果:
167924
7924
答案4
awk -F "=" '{for(i=1;i<=NF;i++){if($i ~ /QUEDBAT/){gsub(/ *INADBAT/,"",$(i+1));gsub(/^[[:space:]]/,"",$(i+1));print $(i+1)};}}' filename
输出
167924
7924