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-*”模式的软件包

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/”)”只是一个简单的正则表达式搜索和替换在任何连字符之后的输入末尾。在 $() 替换之后,外部 sed 命令看起来像这样 '/3.0.0/d' (取决于您正在运行的内核)。它只是删除包含当前内核版本号的行。

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

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

关于bash - Sed 语法 - 分解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11913014/

相关文章:

php - 以下网址 : curl couldn't resolve host 'GET'

linux - 使用 bash 命令删除下一行、空格

linux - 如何使用sed命令更改limits.conf中的ulimit值?

python - 修剪大日志文件

regex - sed 扩展正则表达式的替代方法

bash - 访问在 bash 函数中传递的最后一个参数,然后移动它

sql - 从 PL/SQL 调用 shell 脚本,但 shell 以网格用户而不是 oracle 的身份执行

linux - Shell脚本时间控制

linux - Linux 与 Windows 中的 WMIC 差异

linux - 删除包含日期和另一个表达式的行