如何为ls的输出列着色?


8

标题有点说明了一切:我想得到类似输出的整洁彩色的列ls -al,例如10basetom这个问题的回答

链接答案中语法突出显示的代码段的屏幕快照


好吧,这是一个好主意!但是,您使用的是什么操作系统?
JakeGould

2
SE软件似乎(错误地)突出了Bash语法。看起来它不是按列着色的,而是数字(数字)获得一种颜色,而以大写字母开头的任何事物都获得另一种颜色。每列着色是可行的,但有所不同。
鲍勃

3
一般而言,您可以使用sed或在列分隔符上拆分输出,awk然后插入ANSI转义序列
鲍勃


我在Windows 10 Ubuntu子系统上,但是正在过渡到macOS(考虑到WinX造成的彻底灾难...)
Pirx

Answers:


8

这是可行的awk。不幸的是,由于ls -l未指定的格式,因此不可能提出适用于每个系统的解决方案,因此在某些系统上需要对用于哪一列的颜色进行一些调整。


首先,我们要保留所使用的原始空间ls -l。否则,列对齐将不正确。我们可以使用该FPAT选项来完成此任务,这要归功于这样的答案

ls -la | awk '
    BEGIN {
        FPAT = "([[:space:]]*[^[:space:]]+)";
        OFS = "";
    }

在中awk,每个位置参数($1$2等)都指向一个字段,即当前行上的一列。FPAT上面的选项所做的是将每个字段重新定义为包括所有前面的空格,因此当您将print其退回时,它会保留空格,以使列保持在同一位置。

现在我们可以简单地编辑每个字段以插入颜色代码,然后打印编辑后的输出:

    {
        $2 = "\033[31m" $2 "\033[0m";
        $3 = "\033[36m" $3 "\033[0m";
        $4 = "\033[36m" $4 "\033[0m";
        $5 = "\033[31m" $5 "\033[0m";
        $6 = "\033[36m" $6 "\033[0m";
        $7 = "\033[36m" $7 "\033[0m";
        $8 = "\033[31m" $8 "\033[0m";
        print
    }
'

请注意,各列被复位回为默认值(在0之间的[m)之后。如果您希望颜色跨多列显示,则可以省略该代码。就个人而言,我更愿意独立指定每个列。


您可以在中定义一个可重用的命令.bashrc。例如:

lsc() {
    ls -la | awk '
        BEGIN {
            FPAT = "([[:space:]]*[^[:space:]]+)";
            OFS = "";
        }
        {
            $2 = "\033[31m" $2 "\033[0m";
            $3 = "\033[36m" $3 "\033[0m";
            $4 = "\033[36m" $4 "\033[0m";
            $5 = "\033[31m" $5 "\033[0m";
            $6 = "\033[36m" $6 "\033[0m";
            $7 = "\033[36m" $7 "\033[0m";
            $8 = "\033[31m" $8 "\033[0m";
            print
        }
    '
}

您可能需要重新启动bash会话(或运行source ~/.bashrc),此函数定义才能运行。

从这里,您可以调用lsc,这将为您提供所需的输出:

彩色输出的屏幕截图


很棒的家伙,这几乎是我想要的;-)不过,说真的,我想再加上一点点,并给文件名加上颜色。ls -al --color = auto可以做到这一点,但是如果我只是将--color选项添加到上述解决方案中,则颜色代码似乎被剥夺了。我们可以保留这些吗?
Pirx

第二点评论,这更多是出于好奇:在我最初的问题中引用的答案中,看起来10basetom没有使用以上任何内容,仍然有彩色的列。我想知道这是否是因为他使用了不同版本的ls或某些精美的智能终端?
Pirx

@Pirx答案中的颜色由Stack Exchange软件应用。它不是来自他们的终端。仅仅是因为输出粘贴在代码块中,并且问题具有bash标签,该标签会自动尝试将Bash语法突出显示应用于问题和答案中的任何代码标签...在这种情况下,这实际上是不正确的。出于同样的原因,即使我没有故意为它们着色,代码中的字符串还是红色的。
鲍勃

1
@Pirx使用--color=always。只要您不对文件名列应用其他颜色($9在我的示例中),就awk应将它们传递通过。
鲍勃

@Pirx附带说明--color=always是GNU扩展名,因此,如果您使用的是非GNU系统(例如macOS,其他BSD),则需要安装GNU版本或使用替代版本。
鲍勃

6

这将以ls -alF红色打印第二列,以蓝色打印第三至第八列,以黑色打印第九列:

ls -alF | awk -v black=$(tput setaf 0) -v red=$(tput setaf 1) -v blue=$(tput setaf 4) '{$2=red $2; $3= blue $3; $9=black $9} 1'

这仅是示例。您可以根据自己的喜好自定义内容。

对于那些喜欢将代码分散到多行的用户:

ls -alF | awk -v black=$(tput setaf 0) \
    -v red=$(tput setaf 1) \
    -v blue=$(tput setaf 4) \
    '{
        $2=red $2
        $3= blue $3
        $9=black $9
     }

     1'

细节

tput是一个实用程序,可为您的终端生成各种控制代码。例如, tput setaf n将前景颜色到n其中n的范围可以从0到7

0  Black
1  Red
2  Green
3  Yellow
4  Blue
5  Magenta
6  Cyan
7  White

您可以在此处阅读有关tput其颜色功能的更多信息。

awk代码定义变量black,,red并且分别blue包含黑色,红色和蓝色的终端代码。这些代码位于我们要着色的任何列的开头。

一种技巧是颜色代码不会自行重置。因此,无论您在一行上指定的最后一种颜色,除非指定了另一种颜色命令,否则它将是下一行的默认颜色。


1
呵呵,好的定义变量调用。不知道您可以从内部做到这一点awk!我建议您也包括保留列对齐的模式:)
Bob,

@Bob而且,我喜欢FPAT保持正确间距的技巧。
John1024 '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.