如何在 shell/终端中用 awk 使用 for 循环?

如何在 shell/终端中用 awk 使用 for 循环?

命令

dpkg -l | awk '$2=="ufw" {sub("ubuntu[^[:alpha:]]*$", "", $3); print $3"\t"$2}'

输出:

0.34~rc-0   ufw

现在,我不再像指定包名称$2=="ufw",而是想要迭代并获取所有包的列表,如下所示:

2.20.1-5.1   util-linux
1.0.2-1  zerofree
0.34~rc-0   ufw

编辑
我自己犯了一个语法错误。我应该直接使用相同的命令,删除$2=="ufw"。答案是dpkg -l | awk '{sub("ubuntu[^[:alpha:]]*$", "", $3); print $3"\t"$2}'

答案1

您可以列出dpkg特定软件包的详细信息:

$ dpkg -l util-linux ufw
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                                         Version                     Architecture                Description
+++-============================================-===========================-===========================-==============================================================================================
ii  ufw                                          0.35-0ubuntu2               all                         program for managing a Netfilter firewall
ii  util-linux                                   2.27.1-6ubuntu3.1           amd64                       miscellaneous system utilities

然后你只需要过滤掉标题。

更简单的方法是直接使用dpkg-query和设置格式:

$ dpkg-query -W --showformat '${Version}\t${Package}\n' util-linux ufw
0.35-0ubuntu2   ufw
2.27.1-6ubuntu3.1   util-linux

然后,在中awk,您只需像ubuntu...当前一样删除该部分,而无需进行任何过滤。

答案2

你会发现,当你已删除 $2=="ufw"从 AWK 脚本的开头$2=="ufw" {sub("ubuntu[^[:alpha:]]*$", "", $3); print $3"\t"$2},您就得到了想要的输出。也就是说,您已报告该命令有效:

dpkg -l | awk '{sub("ubuntu[^[:alpha:]]*$", "", $3); print $3"\t"$2}'

您确实应该使用dpkg-query它来以自定义格式打印有关已安装软件包的信息。muru 的回答是完成您在此处尝试执行的特定任务的最佳方法。

这个答案解释了为什么它无法$2=="ufw"awk预期处理每一行输入。


作为GNU Awk 用户指南说,AWK 脚本由指定模式的规则以及花{ }括号中指定该模式匹配时应采取的操作组成。

pattern { action }

当省略模式时,将对输入的每一行执行操作。实际上,这是编写 AWK 规则的最常见方式。

{ action }

这也是您的意图:您希望对每一行输入进行操作并生成一行输出。

{sub("ubuntu[^[:alpha:]]*$", "", $3); print $3"\t"$2}

但你也指定了一个模式:

$2=="ufw" {sub("ubuntu[^[:alpha:]]*$", "", $3); print $3"\t"$2}

这导致您的操作仅应用于第二个字段 ( $2) 等于( ==)的行。但只有一个包的名称恰好是,因此 的输出中只有一行关于它的内容。ufw"ufw"ufwdpkg -l

删除模式会导致对所有输入行执行操作,而不仅仅是有关包的单行ufw

相关内容