将颜色从 ls 通过管道传递到 awk 'print' 语句

Mat*_*DMo 8 ls colors bash pipe awk

这是我昨天提出的问题的后续,在目录列表中显示文件大小的总和

多亏了零比雷埃夫斯毛里茨汉森的正确方向,我现在有了

function dir() {
        ls -FaGl "${@}" | awk '{print; total += $4}; END {print "\t\ttotal: ",total/1024,"KB"}'
}
Run Code Online (Sandbox Code Playgroud)

在我的.bash_profile,它工作得很好。但是,至少在 Linux 上(我还没有机会在 OSX 上尝试它),我ssh在 XP 上使用 PuTTY,我的目录颜色现在不见了。有没有办法通过管道将颜色代码传递给 awkprint语句?

更新

感谢 Sukminder 的回答,添加--color=always可以解决问题,就像auto之前设置的那样。但是,我现在在目录列表的末尾和总行之间有一个空格:

[19:30:58 mattdmo@server ~/webapps/django15 ] $ dir
drwxr-xr-x  7 mattdmo 4096 Mar 24 20:28 ./
drwxr-xr-x 17 root    4096 Mar 18 20:15 ../
drwxr-xr-x  7 mattdmo 4096 Mar 14 14:57 apache2/
drwxr-xr-x  3 mattdmo 4096 Mar 14 14:57 bin/
drwxr-xr-x  2 mattdmo 4096 Mar 24 20:10 lib/
drwxr-xr-x  3 mattdmo 4096 Mar 14 14:57 myproject/
drwxrwxr-x  3 mattdmo 4096 Mar 24 20:28 pigimal/

                total:  28 KB
[19:30:59 mattdmo@server ~/webapps/django15 ] $
Run Code Online (Sandbox Code Playgroud)

关于解决这个问题的任何建议?

Run*_*ium 10

通过使用ls --color=always颜色应该被保留。我不确定它是否特定于 gnu。[来自OP的编辑:是的,是的。]

情况是ls检测输出是否到tty。

如果不是,它通常不会打印颜色,也不会将 “不可打印字符”转换为问号。这可以通过-q 选项添加。

有关该主题的更多信息:ls 输出的行数


gnu coreutils 源 ls; 参考 关于一些颜色数据:


编辑:

对于 gnu coreutils ls:--color=always
对于 OS X 的 ls:设置环境变量CLICOLOR_FORCEG表示颜色。内核符合ls IEEE Std 1003.1-2001。其他选项是在实现之间谨慎的扩展。

好的。对此有更深入的了解。虽然从我读到的人们也在 OS X 上安装了 gnu coreutils,但我猜你可能使用原始的.

ls状态的OS X 手册页

CLICOLOR_FORCE  
    Color sequences are normally disabled if the output isn't directed to a
    terminal.  This can be overridden by setting this flag.  The TERM 
    variable still needs to reference a color capable terminal however
    otherwise it is not possible to determine which color sequences to use.
Run Code Online (Sandbox Code Playgroud)

从来源:

Mac OS X 10.8.2 源-> file_cmds-220.7 -> ls/

从该代码中也可以很快清楚地看出,可以设置

CLICOLOR_FORCE
Run Code Online (Sandbox Code Playgroud)

强制颜色。

当它首先解析参数和setenv颜色时G

    case 'G':
        setenv("CLICOLOR", "", 1);
        break;
Run Code Online (Sandbox Code Playgroud)

并在argv解析后:

/* CLICOLOR is set    AND    is a tty            OR */
if (getenv("CLICOLOR") && (isatty(STDOUT_FILENO) || 
etenv("CLICOLOR_FORCE")))
/*  force cli color is set */
Run Code Online (Sandbox Code Playgroud)

到下一节,如果设置了 TERM,则使用颜色:

if (tgetent(termcapbuf, getenv("TERM")) == 1) {
Run Code Online (Sandbox Code Playgroud)

echo $TERM应该产生一个彩色终端。但是,如果您正常获得颜色,则应该是这种情况。

---

编辑到最后更新:

那就不确定了。它很奇怪。不仅是额外的行,而且你total ...在开始时没有任何行。您可以通过检查这样的输出开始:

function dir() {
/bin/ls -FaGl "${@}" | awk '
    function chr2hex(chr) {
        return sprintf("%02x", index(i2x, chr));
    }
    function str2hex(str) {
        r = ""
        for (i = 1; i <= length(str); ++i)
            r = r chr2hex(substr(str, i, 1));
        return r;
    }
    BEGIN {
        i2x = ""
        for (i = 0; i < 256; ++i)
            i2x = sprintf("%s%c", i2x, i);
        printf("FNR        : %d\n", FNR);
        printf("FIELDWIDTHS: \"%s\"\n", FIELDWIDTHS);
        printf("FS         : \"%s\"\n", str2hex(FS));
        printf("RS         : \"%s\"\n", str2hex(RS));
        printf("OFS        : \"%s\"\n", str2hex(OFS));
        printf("ORS        : \"%s\"\n", str2hex(OFS));
    }
    {
        printf("%2d:%2d:%2d \"%s\"\n", FNR, NR, NF, $0);
        total += $4;
    }
    END {
        printf("%21s: %d %s\n", "total", total / 1024, "KiB");
        printf("FNR        : %d\n", FNR);
        printf("From       : \"%s\"\n", FILENAME);
    }
'
}
Run Code Online (Sandbox Code Playgroud)

应该给你类似的东西——(来自可能是"-"gawk):

$ ./dir testdir
FNR        : 0
FIELDWIDTHS: ""
FS         : "20"
RS         : "0a"
OFS        : "20"
ORS        : "20"
 1: 1: 2 "total 24"
 2: 2: 8 "drwxrwxr-x 6 mattdmo 4096 Apr 17 21:46 ./"
 3: 3: 8 "drwxrwxr-x 8 mattdmo 4096 Apr 18 10:47 ../"
 4: 4: 8 "drwxrwxr-x 2 mattdmo 4096 Apr 17 21:46 ab1/"
 5: 5: 8 "drwxrwxr-x 2 mattdmo 4096 Apr 17 21:46 ab2/"
 6: 6: 8 "drwxrwxr-x 2 mattdmo 4096 Apr 17 21:46 ab3/"
 7: 7: 8 "drwxrwxr-x 2 mattdmo 4096 Apr 17 21:46 ab4/"
                total: 24 KB
FNR        : 7
From       : ""
Run Code Online (Sandbox Code Playgroud)