2

我想知道是否有人可以帮助我理解以下命令。此命令的目的是清除旧内核,但我想了解语法:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge

这是我到目前为止所拥有的:

dpkg -l 'linux-*' - 列出包含“linux-*”模式的包

sed '/^ii/!d;/'... - 查找以ii开头但不包含d 的行;

"$(uname -r | sed "s/(.*)-([^0-9]+)/\1/")"'/d - 命令替换以列出当前内核并仅从版本,sed "s/(.*)... - 搜索任意数量的字符,...([^0-9]... - 从数字 0-9 开始,我不明白这一点:...+)/\1/...

我完全迷失了这个:

s/^[^]* [^]* ([^] )。/\1/;/[0-9]/!d' - 它是否在寻找以字符串开头的空字符?

问候

4

1 回答 1

2

所以,我们sed这里有一个很长的命令要分析:

'/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

它提供了一个在语法上匹配 'linux-*' 的包列表dpkg,这开始有点神秘,但行的开头表示有关包状态的信息。

sed命令本身很长(尽管我犯了更糟的罪!),但相当简单,没有循环或并发症。sed,正如 Fine Manual 告诉你的那样,接受程序作为用分号分隔的命令列表。因此,给定的sed程序有四个命令。

首先,'/^ii/!d'。我们删除不以“ii”开头的行。很简单。我们正在寻找要删除的已安装软件包。

其次,'/'"$(uname -r | sed"s/(.*)-([^0-9]+)/\1/")"'/d'。这是命令行中的命令行(使用bash's $() 语法),所以我们将从内到外工作。目的显然是从我们当前运行的内核的包列表中过滤掉,所以我们不会删除它。的输出uname -r与 debian 包名称不完全匹配,因此它从“3.0.0-generic”之类的内容过滤为“3.0.0”。内部sed命令“s/(.*)-([^0-9]+)/\1/")”只是一个简单的正则表达式搜索和替换,它在任何输入之后切断输入的结尾连字符。在 $() 替换之后,外部sed命令看起来像这样 '/3.0.0/d' (取决于您正在运行的内核)。

第三和第四,'s/^[^]* [^]* ([^] )。/\1/' 和 '/[0-9]/!d' 是最终过滤器。第一个再次是基本的搜索和替换(在 中会更清楚awk),它提取行的第三个字段,这将是包名称,然后我们删除不包含数字的行(否则我们将删除引入内核升级的元包)。

最后,xargs逐行获取其输入并运行您在每一行传递的命令,并将该行附加到其参数中。因此,我们删除了我们找到的每个包。

于 2012-08-11T09:02:17.277 回答