我有这个功能.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
前言
这是解析输出是合理的情况ls
。ls
使用获取数据是错误的程式。在这里,你想要获得一个人类可读的输出,并使其更易于阅读人类。这并不那么重要;如果出现问题,您可能会立即注意到。
即使的实现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
使用时无关紧要。但您的选择可能会有所不同,过多的选项只会损害优雅。使用适合您的任何方法。ls
ls