使用 awk 定义“最小软件包集”的 bash 脚本

使用 awk 定义“最小软件包集”的 bash 脚本

我想编写一个满足以下要求的脚本:

  • 在输入中,获取可通过 获得的软件包列表apt。其中可能有一些软件包是由列表中的其他软件包自动安装的。
  • 在输出中,提供相同的列表,但不提供依赖于列表中其他包的包。

换句话说,我想在 bash 中做什么用户 Francois G 在这个答案中

也许这样的东西已经存在,但有时我喜欢编写脚本来提高我的 bash 脚本编写能力,也是为了好玩。

在我的脑海里,我已经设计好了脚本,但是我遇到了一个技术问题。假设我有这种格式的依赖列表(就是这样的apt-rdepends):

useless-line-1
useless-line-2
useless-line-3
item-1
  fixed-string substring-1-1
  fixed-string substring-1-2
  fixed-string substring-1-3
item-2
  fixed-string substring-2-1
  fixed-string substring-2-2
item-3
item-4
  fixed-string substring-4-1
  fixed-string substring-4-2
  fixed-string substring-4-3
  fixed-string substring-4-4

我想提取与item-1ie相关的段落:

  fixed-string substring-1-1
  fixed-string substring-1-2
  fixed-string substring-1-3

我不是awk专家,但我认为它可以满足我的目的。我无法“构建”正确的命令。由于可能item-2不为人知,我尝试了:

# extract text between item-1 and the next line that starts without blank
$ awk '/item-1/,/^[A-Za-z0-9]/' deplist
item-1

item-1已经符合条件了^[A-Za-z0-9],所以不好。此外,我想从输出中排除item-1和。item-2

提取该部分数据的最佳方法是什么?

答案1

你可以做一些“有状态的”事情,例如。

$ awk -v item='item-1' '$0 !~ /^[[:blank:]]/{p=0} $0 ~ "^" item {p=1} p' deplist
item-1
  fixed-string substring-1-1
  fixed-string substring-1-2
  fixed-string substring-1-3

工作原理:

  • p=0每当我们匹配到以水平空格以外的任何内容开头的行时设置(您可以^[A-Za-z0-9]在这里使用稍微更具体的原始内容)

  • 如果p=1我们匹配所需的^item

  • 随时打印p==1

本质上“当我们匹配所需的项目时打开打印,当我们匹配任何其他项目时将其关闭”。

您需要一些额外的逻辑来跳过匹配的行:

$ awk -v item='item-1' '
      $0 !~ /^[[:blank:]]/{p=0} {m = $0 ~ "^" item ? 1 : 0} m {p=1} p && !m
  ' deplist
  fixed-string substring-1-1
  fixed-string substring-1-2
  fixed-string substring-1-3

在这里,我们执行相同的匹配,但将结果保存在变量中m;然后设置p=1何时m为真(这部分与我们之前的相同);然后我们只打印何时p==1和,m==0即跳过实际匹配发生的行。

相关内容