非图形字符和不可打印字符之间的区别

非图形字符和不可打印字符之间的区别

我的系统:

  • Ubuntu 22.04.3 LTS
  • GNU bash,版本 5.1.16(1)-release (x86_64-pc-linux-gnu)

man ls描述-b如下:

   -b, --escape
          print C-style escapes for nongraphic characters

“控制字符”的维基百科页面状态:

控制字符或非打印字符 (NPC) 是字符集中不代表书面字符或符号的代码点。所有其他字符主要是图形字符,也称为打印字符(或可打印字符),也许“空格”字符除外。

这是模棱两可的。

什么权威资源解释了非图形字符是什么,以及该术语与非打印字符有何不同?

答案1

图形字符将是一个isgraph()/iswgraph()标准函数返回 true 或与正则表达式匹配的值[[:graph:]],即graph语言环境中字符类中的值。

POSIX,该类print必须是一个超集,并且必须graph是脱离的,cntrl并且graph必须是一个超集,并且必须不包括空间(u+0020)字符(没有提及其他空格字符)。upperloweralphadigitxdigitpunct

这个想法是形象的字符将是用墨水绘制的字符,而可打印将是非控制者。

实际上,在 GNU 系统(例如 Ubuntu)上至少printgraph加上类中的非控制字符space。这里使用 glibc 2.35(在 Ubuntu 22.04 上使用)和 UTF-8 语言环境,其中包括:

U+0020 SPACE
U+1680 OGHAM SPACE MARK
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE

虽然space班级有:

U+0009 CHARACTER TABULATION
U+000A LINE FEED
U+000B LINE TABULATION
U+000C FORM FEED
U+000D CARRIAGE RETURN
U+0020 SPACE
U+1680 OGHAM SPACE MARK
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN SPACE
U+2003 EM SPACE
U+2004 THREE-PER-EM SPACE
U+2005 FOUR-PER-EM SPACE
U+2006 SIX-PER-EM SPACE
U+2008 PUNCTUATION SPACE
U+2009 THIN SPACE
U+200A HAIR SPACE
U+2028 LINE SEPARATOR
U+2029 PARAGRAPH SEPARATOR
U+205F MEDIUM MATHEMATICAL SPACE
U+3000 IDEOGRAPHIC SPACE

答案2

此 Bash 脚本列出了与 ASCII 集中每个字符关联的字符类(根据 GNU/awk 定义)。

#! /bin/bash --

Awk='
BEGIN {
    Ctl1 = "SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI ";
    Ctl2 = "DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US SPACE";
    split (Ctl1 Ctl2, Ctl); Ctl[0] = "NUL"; Ctl[127] = "DEL";
    C = "cntrl print graph space blank punct alnum alpha digit lower upper xdigit";
    split (C, Class); 
}
function Char (n, ch, Local, j) {

    printf ("0x%.2X  %5s", n, (n <= 32 || n == 127) ? Ctl[n] : ch);
    for (j = 1; j in Class; ++j) 
        if (ch ~ "[[:" Class[j] ":]]") printf ("  :%s:", Class[j]);
    printf ("\n");
}
{ for (j = 0; j < 128; j++) Char( j, sprintf ("%c", j)); }
'
    echo | awk -f <( printf '%s' "${Awk}" ) 
    

相关内容