Bash Sed语法-分解

Bash Sed语法-分解,bash,sed,Bash,Sed,我想知道是否有人能帮助我理解以下命令。此命令的目的是清除旧内核,但我想了解语法: 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-*”模式的软件包 s

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

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'-它正在寻找字符串开头的空字符吗


关于

因此,我们这里有一个长的
sed
命令来分析:

'/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'
它在
dpkg
语法中提供了一个与“linux-*”匹配的包列表,开始时有点神秘,但行的开头表示有关包状态的信息

sed
命令本身相当长(尽管我犯了更糟的错误!),但相当简单,没有循环或复杂情况。
sed
,正如《精细手册》所告诉您的,接受程序作为用分号分隔的命令列表。因此,给定的
sed
程序有四个命令

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

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

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


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

Close;但是您并没有完全分解它。几乎整个命令,直到xargs,都只是第一个sed的一个长参数。看到了吗?什么时候您可以将字符串紧挨着放,如'arg'$(command)”第二,阅读sed的手册页。它实际上非常灵活,有一大堆神秘的命令。/^ii/!d;是一个命令,以;结尾,其中d指定sed的指令,前面的位描述它所应用的行。继续分析!编辑:实际上,我刚刚没有ried正在运行这个命令,我收回了我说过的关于第三个命令的话。实际上,你发布的原始命令中有一个bug,它只是意外地起作用。在awk中它会更清楚!原始作者显然是想写
s/^[^]**\([^]*\)./\1/
。哦,好吧。