14

with cat, I use the -A flag and I can't find what these characters mean anywhere. For example:

cat /proc/cpuinfo > output

cat -A output

One of the lines is this:

processor^I: 7$

I know the $ means new line, but what does ^I mean?

What does ^@ mean?

I'm trying to figure out what type of white space cpuinfo spits out so I can strip them in my C program, but I'm having a difficult time doing that.

1
  • When executing for instance cat -A <<< $'\\0\a\b\t\n\v\f\rÉÖÈ' in bash (where in the input $'string' the content of string is interpreted as ANSI C would: with special characters as backslash notation), one can see outputs in the caret notation.
    – The Quark
    Commented Sep 17, 2021 at 8:19

4 Answers 4

23

^I and ^@ use the common “caret” notation for control characters. ^I means the ASCII character control-I, i.e. character 9, which is a tab. ^@ means the ASCII character control-@, i.e. character 0, which in C is the string end character. The general form is ^c where c is an uppercase letter or one of @[\]^_, representing the byte whose value is that of c minus 64; and ^? representing the byte value 127 (which is the byte value of ? plus 64).

There's another, far less standard notation used by cat -A: non-ASCII bytes (i.e. byte values 128 and above) are shown as M- followed by the representation of the byte whose value is 128 by less (i.e. the byte value with the upper bit flipped).

cat -A isn't the best way to understand visually ambiguous output. A hexadecimal transcript gives you more precise information, e.g.

od -t x1 /proc/cpuinfo
hd /proc/cpuinfo

But from a C program you can just use scanf to parse the information. All ASCII whitespace is whitespace to scanf, and with files in /proc you know that the format will be valid.

4
  • Thanks for the hd suggestion. I've always used hexdump -C (combining hex with text for printable character), but it turns out hd does the same thing. IDK if hd existed ~15 years ago when I was first finding a hexdump command I liked. Commented Aug 25, 2016 at 5:20
  • +1 just for the hd suggestion. I've been using od -t x1 and xxd -g1 (xxd is part of vim, btw). Commented Aug 25, 2016 at 7:09
  • There are various extensions of ASCII to use more than the standard 128 characters. Which one is the one used in bash?
    – The Quark
    Commented Sep 17, 2021 at 8:22
  • 1
    @TheQuark You can choose. These days most systems default to UTF-8 and there's little reason to pick anything else. Commented Sep 17, 2021 at 8:34
7

In this context, the ^ is being used as a short-cut for "control". So ^A means "control-A", which is ASCII character 1. ^I means control-I or ASCII 9, also known as TAB. ^@ is therefor ASCII 00, or the NUL character.

These characters are commonly known as "control characters".

You may also see M-; this means "meta" and means the top bit is set (add 128 to the ASCII value of the following character).

6

As an addendum, the other answers don't make completely clear the relationship between letters and control-characters

The ASCII character set can be displayed in a table like this

NUL   SP  @  `
SOH   !   A  a
STX   "   B  b
ETX   #   C  c
EOT   $   D  d
ENQ   %   E  e
ACK   &   F  f
BEL   '   G  g
BS    (   H  h
HT    )   I  i
LF    *   J  j
VT    +   K  k
FF    ,   L  l
CR    -   M  m
SO    .   N  n
SI    /   O  o
DL    0   P  p
DC1   1   Q  q
DC2   2   R  r
DC3   3   S  s
DC4   4   T  t
NAK   5   U  u
SYN   6   V  v
ETB   7   W  w
CAN   8   X  x
EM    9   Y  y
SUB   :   Z  z
ESC   ;   [  {
FS    <   \  |
GS    =   ]  }
RS    >   ^  ~
US    ?   _  DEL

You may know that the control character named TAB can be inserted into a document by pressing the keyboard key labelled TAB. You may also be aware that you can achieve the same thing by holding down the CTRL key and pressing I. The control key labelled CTRL exists as a way of entering ASCII control characters.

You can see from the table above that the "I" character is on the same row as the HT (Horizontal Tabulation, i.e. TAB) character.

Nowadays we might write this character as CTRL+I but in the past it was more common to abbreviate this as ^I

From the table you can also see that "@" is on the same line as "NUL" and so ^@ represents NUL, the null character 0x00.

The arrangement in the table illustrates that the numeric value ("code point") assigned to these characters in ASCII is such that each of the letters is 0x40 plus the value of the corresponding control character.

3

Use a hex viewer:

% hexdump -C /proc/cpuinfo | sed -n /processor/p
00000000  70 72 6f 63 65 73 73 6f  72 09 3a 20 30 0a 76 65  |processor.: 0.ve|
00000340  74 3a 0a 0a 70 72 6f 63  65 73 73 6f 72 09 3a 20  |t:..processor.: |
% 

And then consult ascii(7) or a similar table to lookup what particular codes are, here 09 or horizontal tab.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .