什么是正确的 awk 正则表达式来匹配文件夹、隐藏文件夹、普通文件,所以我可以使用转义码为它们着色,以及将语法放在哪里

What is the right awk regex to match folder, hidden folder, normal file, so I can colorize them using escape code, and where to put the syntax

ls -lhAXF --group-directories-first "$@" | awk '
    BEGIN {
        FPAT = "([[:space:]]*[^[:space:]]+)";
    } {
         = "3[1m" "3[31m"  "3[0m";
         = "3[1m" "3[32m"  "3[0m";
         = "3[1m" "3[33m"  "3[0m";
         = "3[34m"  "3[0m";
         = "3[1m" "3[35m"  "3[0m";
         = "3[1m" "3[36m"  "3[0m";
         = "3[1m" "3[37m"  "3[0m";
         = "3[1m" "3[33m"  "3[0m";
        print
    }'

link to the output

实现以下目标的正确语法是什么:

  1. 颜色普通目录为红色
  2. 颜色隐藏目录为蓝色
  3. 将常规文件颜色变为绿色

我知道的:

  1. 用正则表达式匹配普通目录,就像在 $9 列中以 '/' 结尾的任何单词一样
  2. 将隐藏目录与正则表达式匹配,就像任何以“.”开头的单词一样在列 $9
  3. 将常规文件与正则表达式匹配,就像不匹配以“/”结尾且不匹配以“.”开头的行的其余部分一样
  4. 我知道类似的东西:awk ' ~ /something/' 匹配正确的列

但是语法放在哪里,语法是什么样的?

我想在使用像“\033[32m”这样的转义码匹配后对正则表达式的结果进行着色

如注释中所述,不推荐解析 ls 的输出; ls 仅适用于人类。但如果你绝对想这样做,你可以尝试以下方法:

ls -lhAXF --group-directories-first "$@" | awk '
  BEGIN {FPAT = "([^[:space:]]+[[:space:]]*)"}
  {if( ~ /^d/ &&  ~ /^\./)  = "3[31m" 
   else if( ~ /^d/)  = "3[32m" 
   else  = "3[33m" 
   for(i=1;i<NF;i++) $i = sprintf("3[3%dm%s", i, $i)
    = "3[1m" 
   $NF = $NF "3[0m"
   print}'

我们首先将字段重新定义为word-spaces而不是spaces-word,因为这样可以更容易地检测隐藏目录、非隐藏目录和非目录:相关部分现在位于字段的开头:

  • ~ /^d/ => 目录
  • ~ /^\./ => 隐藏

我们还通过抑制无用的中间 ANSI 代码和使用 for 循环将 ANSI 颜色代码添加到每个字段来简化一点。

剩下的就很简单了。我们首先根据类型将颜色 ANSI 转义代码添加到 </code>(名称字段)。接下来,我们根据字段索引将颜色 ANSI 转义代码添加到其他字段。最后,我们将粗体代码添加到 <code> 并将重置代码附加到最后一个字段,然后打印。


Ed Morton 编辑:gawk -o- 为提高易读性对上面的脚本进行了漂亮的打印:

BEGIN {
        FPAT = "([^[:space:]]+[[:space:]]*)"
}

{
        if ( ~ /^d/ &&  ~ /^\./) {
                 = "3[31m" 
        } else if ( ~ /^d/) {
                 = "3[32m" 
        } else {
                 = "3[33m" 
        }
        for (i = 1; i < NF; i++) {
                $i = sprintf("3[3%dm%s", i, $i)
        }
         = "3[1m" 
        $NF = $NF "3[0m"
        print
}

您正在尝试测试 ls -F 应用于目录名称的尾部斜杠。

你要找的是这样的:

BEGIN {
    red = "3[31m" # dir
    green = "3[32m" # file
    blue = "3[36m" # hidden dir
    reset = "3[0m"
}

{
    if ( ~ /\/$/) {
        if ( ~ /^\./) {
             = blue  reset
        }
        else {
             = red  reset
        }
    }
    else {
         = green  reset
    }
}

但是 如果文件名包含 spaces/tabs.

它会中断

您可以测试第 1 列(ls -l)的第一个字符,而不是(d-)……但是您最好查看像 statfind.