【问题标题】:exclude stdout based on an array of words基于单词数组排除标准输出
【发布时间】:2021-05-11 00:50:00
【问题描述】:

问题:

是否可以根据单词数组排除某些命令输出其输出?**

为什么?

在 Ubuntu/Debian 上,有两种方法可以列出所有可用的 pkg:

  1. apt list(显示所有可用的 pkgs,以及已安装的 pkgs)
  2. apt-cache search .(显示所有可用的 pkgs,也安装了 pkgs)

不同之处在于,第一个命令,您可以使用grep -v 排除所有已安装的 pkg,问题与第一个不同,第二个命令您不能排除这些,因为“已安装”一词不存在。第一个命令的问题是它没有显示 pkg 描述,所以我想使用 apt-cache search . 但不包括所有已安装的 pkg。

# List all of my installed pkgs,
# Get just the pkg's name,
# Swap newlines for spaces,
# Save this list as an array for exclusion.

INSTALLED=("$(apt list --installed 2> /dev/null | awk -F/ '{print $1}' | tr '\r\n' ' ')")

然后我尝试了:

apt-cache search . | grep -v "${INSTALLED[@]}"

不幸的是,这不起作用,因为我仍然看到我安装的 pkg,所以我猜测它不包括数组中的第一个 pkg,而不是其余的。

再次提前感谢您!

【问题讨论】:

  • 如果您edit 您的问题是显示minimal reproducible example 具有简洁、可测试的样本输入(即您提到的各种命令的输出,这些命令提供您想要比较的各种列表)和预期输出您想要编写的用于对该输入进行操作的工具,那么我们可以为您提供帮助。
  • 现在好点了吗?抱歉,我是新手,不理解反对意见,但我现在将问题编辑为简短而甜蜜。
  • 不,你列出了一些命令并说你想要一个工具来处理这些命令的输出。您需要提供这些命令的输出示例(您要编写的工具的输入)以及在给定该输入的情况下您要编写的该工具的最终输出。希望这是有道理的,如果没有看到How to Ask
  • 现在就像你说你想比较“fluffy”的输出和“bunny”的输出并寻求帮助 - 好的,向我们展示输出的样子以及你想用它做什么。给我们一个minimal reproducible example,提供具体的输入和输出,我们可以测试潜在的解决方案。

标签: arrays shell awk sed grep


【解决方案1】:

请您尝试以下方法:

#!/bin/bash

declare -A installed                            # an associative array to memorize the "installed" command names

while IFS=/ read -r cmd others; do              # split the line on "/" and assign the variable "cmd" to the 1st field
    (( installed[$cmd]++ ))                     # increment the array value associated with the "$cmd"
done < <(apt list --installed 2> /dev/null)     # excecute the `apt` command and feed the output to the `while` loop

while IFS= read -r line; do                     # read the whole line "as is" because it includes a package description
    read -r cmd others <<< "$line"              # split the line on the whitespace and assign the variable "cmd" to the 1st field
    [[ -z ${installed[$cmd]} ]] && echo "$line" # if the array value is not defined, the cmd is not installed, then print the line
done < <(apt-cache search .)                    # excecute the `apt-cache` command to feed the output to the `while` loop
  • 关联数组installed用于检查命令是否 已安装。
  • 第一个while 循环扫描已安装的命令列表并 将命令名称存储在关联数组 installed 中。
  • 第二个while 循环扫描可用的命令列表,如果 在关联数组中找不到命令,然后打印它。

顺便说一句,您的试用代码以#!/bin/sh 开头,它以sh 运行,而不是bash。 请确保它看起来像#!/bin/bash

【讨论】:

  • 完美运行!太感谢了!刚刚接受了这个答案!不幸的是,我 -1 询问了它:'(
  • 感谢您的礼貌反馈。我已经补偿了不合理的-1。
【解决方案2】:

对不起,如果我误解了,但您只是想获取未安装的软件包列表,对吗?

如果是这样,你可以这样做 -

apt list --installed=false | grep -v '\[installed'

【讨论】:

  • 1) 如前所述,我想使用 apt-cache search .,因为它包含 pkg 描述。 2)如果使用--installed=false,则不需要grep -v \[installed(无论如何都没有列出安装)。