我有一个文件可以复制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中使用/打印它们。 / p>
问题是,我对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}}'
文件'数据'包含我上面粘贴的块。代码应该,如果' age'输入小于数据文件中的Time参数(我的awk代码为$ 4),返回ID参数,但不返回任何内容。
如果我删除if语句并打印$ 4而不是$ 2,这是我的输出
Enter age
1
1030455
1004
2144
2086
0
所以我想也许这句空白行以某种方式搞砸了我的AWK版画?是否有一种简单的方法可以在保留其他数据的同时忽略该空行?
答案 0 :(得分:2)
这就是你如何使用awk来生成所需的值,作为输入中每个“行”块的每一行上的一组制表符分隔的字段:
$ 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
和delete array
。
当你说“并将这些参数中的每一个存储到一个不同的变量或数组中”时,它可能意味着其中一件事情,所以我会把那部分留给你,但你可能会找到类似的东西:
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
。
在您编辑问题以告诉我们有关您的问题的更多信息之前,我们无法从这一点猜出正确的解决方案。
答案 1 :(得分:1)
在第一级,您拥有用于运行任何其他子进程的shell。从子进程内部修改父项环境是不可能的。当您运行bash脚本文件(正确+x
)时,它会被生成为新进程(子进程)。它可以设置它自己的环境但是当它结束它的实时时你会回到原来的(父)。
您可以在bash上设置一些变量,并将export
设置为它的环境。它将由它的孩子继承。但是它不能在相反的方向上完成(父亲不能从其子女继承)。
如果您希望在当前bash的上下文中从脚本文件执行某些命令,您可以source
脚本文件。 source ./your_script.sh
或. ./your_script.sh
会为您做到这一点。
如果你需要运行awk
为你过滤一些数据并将结果保存在bash中,你可以这样做:
awk ... | read foo
这适用于read
是shell buildin函数而不是外部进程(检查type read
,help
,help read
,man bash
以自行检查)
或:
foo=`awk ....`
您可以使用许多其他结构。无论您使用什么bash脚本,请将您的代码与bash pitfalls webpage进行比较。