linux - 使用 AWK 并将结果设置为 bash 变量/数组?

标签 linux bash awk

我有一个文件可以复制 mySQL 的 show processlist 命令的结果。 该文件如下所示:

*************************** 1. row ***************************
Id: 1
User: system user
Host:
db: NULL
Command: Connect
Time: 1030455
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 2
User: system user
Host:
db: NULL
Command: Connect
Time: 1004
State: Has read all relay log; waiting for the slave
       I/O thread to update it
Info: NULL

它会以相同的结构继续进行几次。

我想使用 AWK 只获取这些参数:时间、ID、命令和状态,并将这些参数中的每一个存储到不同的变量或数组中,以便我以后可以在我的 bash shell 中使用/打印它们。

问题是,我的 AWK 很糟糕,我不知道如何将我想要的参数从文件中分离出来,并将它们设置为 bash 变量或数组。

非常感谢您的帮助!

编辑:到目前为止,这是我的代码

echo "Enter age"
read age
cat data | awk 'BEGIN{ RS="row"
FS="\n"
OFS="\n"}
{ print $2,$7}
' | awk 'BEGIN{ RS="Id"}
{if ($4 > $age){print $2}}'

文件“数据”包含我在上面粘贴的 block 。如果输入的“年龄”小于数据文件中的时间参数(在我的 awk 代码中为 $4),代码应该返回 ID 参数,但它什么也不返回。

如果我删除 if 语句并打印 $4 而不是 $2 这就是我的输出

Enter age
1

1030455
1004
2144
2086
0

所以我在想,也许那个空行以某种方式弄乱了我的 AWK 打印?有没有一种简单的方法可以在保留我的其他数据的同时忽略该空白行?

最佳答案

这就是您如何使用 awk 生成您想要的值,作为一组制表符分隔的字段,在输入的每个“行” block 的每一行上:

$ cat tst.awk
BEGIN {
    RS="[*]+ [[:digit:]]+[]. row [*]+\n"
    FS="\n"
    OFS="\t"
}
NR>1 {
    sub(/\n$/,"")     # remove the trailing newline
    gsub(/\n\s+/," ") # compress all multi-line fields into single lines
    gsub(OFS," ")     # ensure the only OFS in the output IS between fields

    delete n2v
    for (i=1; i<=NF; i++) {
        name = gensub(/:.*/,"","",$i)
        value = gensub(/^[^:]+:\s+/,"","",$i)
        n2v[name] = value
    }

    if (n2v["Time"]+0 > age) {  # force a numeric comparison
        print n2v["Time"], n2v["Id"], n2v["Command"], n2v["State"]
    }
}

$ awk -v age=2000 -f tst.awk file
1030455 1       Connect Waiting for master to send event

如果目标年龄已经存储在 shell 变量中,只需从同名的 shell 变量中初始化 awk 变量:

$ age="2000"
$ awk -v age="$age" -f tst.awk file

以上代码使用 GNU awk 实现多字符 RS(您已经拥有)、gensub()\s删除数组

当你说“并将这些参数中的每一个存储到不同的变量或数组中”时,它可能意味着几件事之一,所以我会把那部分留给你,但你可能正在寻找类似的东西:

arr=( $(awk '...') )

awk '...' |
while IFS="\t" read -r Time Id Command State
do
    <do something with those 4 vars>
done

但到目前为止,最有可能的情况是您根本不想使用 shell,而只是留在 awk 中。

请记住 - 每次您在 shell 中编写循环只是为了操作文本时,您的方法都是错误的。 UNIX shell 是调用 UNIX 工具的环境,用于一般文本操作的 UNIX 工具是 awk

不过,除非您编辑您的问题以告诉我们更多关于您的问题的信息,否则我们无法从现在开始猜测正确的解决方案是什么。

关于linux - 使用 AWK 并将结果设置为 bash 变量/数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28391324/

相关文章:

linux - linux中的mount系统调用无法通过df命令显示文件系统的挂载点

ruby - 在一条线上搜索和标记成对模式

linux - 基于两列(双向)删除重复行,只保留一列

bash - 等待进程完成

bash - 字符串插值在 bash 中如何工作?

bash - 如何在 bash 和/或使用 awk 中的单个列中进行数学运算?

linux - 如果 file1 的 B 列 = file2 的 B 列,则将 file1 的 A 列替换为 file2 的 A 列

使用 SNMP 监视 Java 应用程序

python - 如何在python中为linux设置复杂的环境变量?

c - Linux C : What does the "S_Ixxxx" permission flag's "S" and "I" actually mean?