突出显示 ps 输出的第 n 列

突出显示 ps 输出的第 n 列

我正在尝试找到突出显示某些输出的特定列的最佳方法。具体来说,我试图突出显示第六名%cpu命令的列(即):

ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu

我找到了一个线在这里关于类似的主题,其中接受的答案是使用sed添加颜色。这就是我想要做的,但我似乎无法让它发挥作用。

这是我到目前为止所得到的:

ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu | head  | sed -e $'s/ *[^ ]* /\033[1;33m&\033[0m/'

其中突出了第一的浅黄色柱。我试图让正则表达式工作,以便它获得第六列,但似乎无法让它工作。

在同一个脚本中,我将做同样的事情,除了突出显示7号列(内存)。所以我希望有一种更简单的方法来处理这个问题。

答案1

在我的 Debian 9 中,我有ps该报告(即ps --version报告)ps from procps-ng 3.3.12。手册指出:

这支持 AIX 格式描述符,其工作方式有点类似于和 的ps格式化代码。例如,可以使用以下命令生成正常的默认输出:。printf(1)printf(3)ps -eo "%p %y %x %c"

事实证明,我可以在使用此语法时在格式中包含任意字符串。混合 AIX 和非 AIX 格式描述符通常不起作用,并且所讨论的格式无法完全转换为 AIX(我认为 AIX 可以替代pidppidtimeusertty%cpu和,vsizecommand不能替代%mem)。幸运的是,一个人可以使用多个-o.每个都-o可以独立地使用 AIX 或非 AIX 格式描述符。

在您的情况下,您想要突出显示的列 ( %cpu) 可以表示为 AIX 格式描述符 ( %C)。这使得突出显示它相对容易:

ps -eo pid,ppid,time,user,tty -o $'\033[1;33m%C\033[0m ' -o %mem,vsize,command --sort -%cpu

笔记

  • 我依靠$'…'Bash 中的语法来扩展\033[1;33m和类似;鞋底ps不会扩展此类字符串。或者$(printf '…')可用于生成转义序列。
  • 该格式包含一个尾随空格,用于将突出显示的列与下一列分隔开。
  • 这种方法使您可以轻松突出显示多个连续的列。
  • 如果突出显示开始的列无法表示为 AIX 格式描述符,那么前一列也许可以。您可以将其注入到指定前一列的格式末尾,而不是\033[1;33m在指定第一个突出显示的列的格式前面注入。
  • \033[0m类似地:您可以将其注入到指定下一列的格式前面,而不是在指定最后一个突出显示的列的格式末尾注入。
  • 如果您需要在列之间切换颜色,并且两列都不能表示为 AIX 格式描述符,则可以在中间添加一个虚拟列,其唯一目的是提供正确的转义序列。要注入任意字符串,您需要一种类似于 AIX 格式的格式,否则ps将尝试将该字符串解释为非 AIX 格式(即使它没有失败,这也不是您想要的)。这意味着您至少需要一个您提供的格式的可扩展项%??这里不是字面意思,而是通配符)。

以下示例通过使用虚拟列来突出显示所需列。“真实”列使用非 AIX 格式描述(因此它们可能无法全部用 AIX 格式描述符替换,但解决方案仍然有效)。%%用于告知ps“颜色切换”格式与 AIX 类似;%%进行ps打印%,因此\b(退格键)会立即打印;在每种情况下,后面的输出都会覆盖不需要的%

    ps -eo pid,ppid,time,user,tty -o $'%%\b\033[1;33m' -o %cpu -o $'%%\b\033[0m ' -o %mem,vsize,command --sort -%cpu

如果需要,您可以在最后放置一个虚拟列。在这种情况下,格式仍然需要尾随空格(以覆盖不需要的%)。

  • 同样,您可以生成视觉分隔符。例子:

      ps -eo pid,ppid,time,user,tty -o $'%%\b|X| ' -o %cpu,%mem,vsize,command --sort -%cpu
    

在这种情况下,可以使用 AIX 描述符指定相邻列,因此使用 like 更容易-o '%y |X| %C',不需要%%\b。然而,一般来说,这是生成自定义列的一种方法,即使相邻列不能用 AIX 格式描述符表示。

  • 如果进一步解析输出(例如使用sed),那么请记住像 (expanded)\033[0m或 (expanded) 这样的子字符串%%\b存在,即使您看不到它们。

这个解决方案不可移植,但我发现代码比该方法与sed。特别是当将许多不同的颜色应用于不同的列时。在前面或中间添加一列、删除或重新排列列都非常简单;而使用sed它则需要仔细调整正则表达式。

答案2

唐克里斯斯蒂发布了一个非常简单的解决方案,只需在最后一个结束引号之前添加所需的列号:

 ps -eo pid,ppid,time,user,tty,%cpu,%mem,vsize,command --sort -%cpu | head  | sed -e $'s/ *[^ ]* /\033[1;33m&\033[0m/6'

相关内容