如何在 Xubuntu 16.04.6 中对齐 ls 命令输出的列?

如何在 Xubuntu 16.04.6 中对齐 ls 命令输出的列?

我有这个功能.bashrc

{ ls -lhNGhgF --color=always --group-directories-first --time-style="+%d-%b-%Y $newline%H:%M" | awk '
            { 
            $3 ="\033[1;31m"        $3 "\033[0m";
            $4 ="\033[1;48;5;196m"  $4 "\033[0m"; 
            $5 ="\033[1;30m"        $5 "\033[0m"; 
            print; 
            }
      '
}

它可以工作,但是输出的列未对齐。我该如何修复?

答案1

前言

这是解析输出是合理的情况lsls使用获取数据是错误的程式。在这里,你想要获得一个人类可读的输出,并使其更易于阅读人类。这并不那么重要;如果出现问题,您可能会立即注意到。

即使的实现ls支持您需要的所有选项, 也可能产生略有不同的输出。因此, 的任何此类问题的解决方案都必须根据 进行量身定制ls

记录显示:我的测试平台是 Kubuntu 18.04.2 LTS。


代码

使用此功能:

lsi() {

local c3=$'\033[1;31m'
local c4=$'\033[1;48;5;196m'
local c5=$(printf '\033[1;30m')
local c0=$'\033[0m'

command ls -hGgF --color=always --group-directories-first --time-style="+%d-%b-%Y $newline%H:%M" "$@" \
| sed -E "s|([^ ]+ +)([^ ]+ +)([^ ]+ +)([^ ]+)( +[^ ]+ +)|\1\2$c3\3$c0$c4\4$c0$c5\5$c0|"

}

解释:

首先,我将我们需要的字符串存储为局部变量。我使用的$''语法在 Bash 中有效,但 除外c5(出于教育原因)是从 的输出中检索的printf。重点是 的方法printf即使在 中也能起作用sh,因此如果您需要此函数在无法理解 Bash 的 的 shell 中工作$'',您就会知道方法。

然后我使用sed扩展正则表达式进行搜索和替换。除最后一列之外的任何列都可以匹配[^ ]+ +,这意味着“至少一个非空格和至少一个空格”。在替换中,第一组括号 ( (…)) 匹配的内容称为\1;第二组括号匹配的内容称为\2;等等。这样,我可以匹配前五列并使用“替换”它们\1\2\3\4\5。这个唯一的操作是无操作,直到我在正确的位置注入之前存储的字符串:

 \1\2$c3\3$c0$c4\4$c0$c5\5$c0
     ^^^  ^^^^^^  ^^^^^^  ^^^ 

笔记:

  • 您可能已经注意到,第 4 列和第 5 列由重复两次的Universal匹配,([^ ]+)( +[^ ]+ +)而不是由 Universal 匹配。如果是这样,那么这些列之间的空格字符在逻辑上应该属于第 4 列,因此它们会打印为红色,因为您为第 4 列选择了背景颜色。将它们包含在第 5 列中可以解决问题。([^ ]+ +)([^ ]+ +)([^ ]+ +)

  • 我没有在第一列和第二列之间注入任何内容,因此我可以用一组括号(即([^ ]+ +[^ ]+ +))匹配它们,替换字符串将如下所示:\1$c3\2$c0$c4\3$c0$c5\4$c0。然后\1将引用两列,\4将引用第五列。我决定避免混淆,并使这些数字与列的自然编号保持一致。

  • command ls确保函数不会运行名为 的函数ls,即使已定义该函数。此处这有点过分,但如果您决定将其重命名lsi为,ls则将command有助于您避免不必要的无限递归。

  • "$@"在调用结束时添加了ls,以便我能够执行lsi /lsi /dev/sd*等等。请注意,这还允许我指定可能运行良好(例如lsi -a)或运行不太好的附加选项(它们可能会移动列而不移动颜色,例如lsi -i)。

  • 我压缩了选项。使用时-g您不需要-l;并且您有-h两次;并且我认为在管道中-N使用时无关紧要。但您的选择可能会有所不同,过多的选项只会损害优雅。使用适合您的任何方法。lsls

相关内容