我正在使用 While Read Line 状态来解析我们的 Openstack Swift 帐户。下面是我用来查找具有特定创建/修改日期的所有数据的语句中的一些代码。
首先,我运行命令来获取帐户中所有容器的列表:
swift list -A http://sslabapi/auth/v1.0 -U qa04 -K <Account Password> > containers.txt
该命令将输出一个列表,如下所示:
ffd5eef3-2b75-4d4f-b30c-b9836b32a34c
下面是我可以运行来查看容器内容的命令:
swift list -l -A http://sslabapi/auth/v1.0 -U qa04 -K <Account Password> ffd5eef3-2b75-4d4f-b30c-b9836b32a34c
1507732 2017-09-27 19:55:57 application/octet-stream ffd5eef3-2b75-4d4f-b30c-b9836b32a34c.FR.02
1812122 2017-09-27 19:55:57 application/octet-stream ffd5eef3-2b75-4d4f-b30c-b9836b32a34c.FS.02
我编写了以下命令来解析所有容器,并对容器中具有特定日期“2017-09-27”的任何对象发出警报:
while read line; do echo -e swift list -l -A http://sslabapi/auth/v1.0 -U qa04 -K <Account Password> $line | bash; done < containers.txt | awk '{ if ($2 == "2017-09-27") print $0}'
有没有办法在 print $0 语句中打印 $line 的内容?例如,输出将类似于:
ffd5eef3-2b75-4d4f-b30c-b9836b32a34c 1812122 2017-09-27 19:55:57 application/octet-stream ffd5eef3-2b75-4d4f-b30c-b9836b32a34c.FS.02
编辑:
我仍然有这个问题,我现在不知道为什么。文件“containers.txt”有一个容器列表(它们是文件或对象的根目录),这些容器被插入到我的命令中并且可以正常工作。我似乎无法在 AWK 语句中打印相同的 GUID。这是必需的,以便我能够找到 AWK 语句中标记的文件的根目录。以下两个语句产生完全相同的输出:
while read line; do echo -e swift list -l -A http://sslabapi/auth/v1.0 -U auto02 -K [ACCOUNT PASSWORD] $line | bash; done < containers2.txt | awk -v l="$line" '$2 == "2018-05-08" { print l, $0 }'
while read line; do echo -e swift list -l -A http://sslabapi/auth/v1.0 -U auto02 -K [ACCOUNT PASSWORD] $line | bash; done < containers2.txt | awk '$2 == "2018-05-08" {print $0 }'
输出如下所示: 9923 2018-05-08 15:56:34 application/octet-stream 4919d1c8-f5c7-448f-98ad-29d88f1a5a84.BC.01
理想情况下,我希望它在输出中使用根容器进行生成和输出,如下所示:
4919d1c8-f5c7-448f-98ad-29d88f1a5a84 9923 2018-05-08 15:56:34 应用程序/八位字节流 4919d1c8-f5c7-448f-98ad-29d88f1a5a84.BC.01
答案1
你需要把awk
里面循环while
,而不是从外部通过管道进入。那时循环变量已经超出了范围(并且在任何情况下,它也会采用几个不同的值,所以您想看到哪一个?)。
按照这些思路应该没问题:
while read line
do
swift list -l -A http://sslabapi/auth/v1.0 -U qa04 -K <Account Password> "$line" | awk -v line="$line" '{ if ($2 == "2017-09-27") print line $0}'
done < containers.txt
我把echo
/| bash
拿出来是因为他们没有取得任何成果。这确实意味着您将启动多个awk
进程而不是一个进程,但这在这里不会成为问题。
如果您愿意,还可以在循环内连接线路和数据:
swift list -l -A http://sslabapi/auth/v1.0 -U qa04 -K <Account Password> "$line" | xargs -L 1 echo "$line"
这xargs -L 1
命令将为该命令的echo "$line" ABC
每一行ABC
输出运行swift list
,其效果是在每一行前面加上$line
.然后,您可以通过管道连接到awk
外部的现有设备,调整您的测试,$3
而不是$2
进行补偿。
其中哪一个效果更好将取决于您的最终目标是什么以及数据的分布方式,但就此处而言,两者是等效的。我个人更喜欢第二个版本,但这并不重要。
答案2
试试这个awk
awk -v l=$line '{if ($2 == "2017-09-27") print l" "$0}'
我的测试样本:
# echo $line
abc
# cat tt.txt
hi 2017-09-27 test1
hi 2017-09-28 test1
# awk -v l=$line '{ if ($2 == "2017-09-27") print l" "$0}' tt.txt
abc hi 2017-09-27 test1