ZhangZhihui's Blog  

If you have a known octal or hexadecimal value (at script-writing time), you can just use printf:

 

# POSIX
printf '\047\n'

# bash/ksh/zsh and a few other printf implementations also support:
printf '\x27\n'

In locales where the character encoding is a superset of ASCII, this prints the literal ' character (47 is the octal ASCII value of the apostrophe character) and a newline. The hexadecimal version can also be used with a few printf implementations including the bash builtin, but is not standard/POSIX.

printf in bash 4.2 and higher, and in ksh93, supports Unicode code points as well:

 

# bash 4.2, ksh93
printf '\u0027\n'

Another approach: bash's $'...' quoting can be used to expand to the desired characters, either in a variable assignment, or directly as a command argument:

 

ExpandedString=$'\x27\047\u0027\U00000027\n'
printf %s\\n "$ExpandedString"

# or, more simply
printf %s\\n $'\x27\047\u0027\U00000027\n'
zzh@ZZHPC:~$ printf '\047\n'
'
zzh@ZZHPC:~$ printf '\x27\n'
'
zzh@ZZHPC:~$ printf '\u0027\n'
'
zzh@ZZHPC:~$ ExpandedString=$'\x27\047\u0027\U00000027\n'
printf %s\\n "$ExpandedString"
''''

zzh@ZZHPC:~$ printf %s\\n $'\x27\047\u0027\U00000027\n'
''''

zzh@ZZHPC:~$

 

If you need to convert characters (or numeric ASCII values) that are not known in advance (i.e., in variables), you can use something a little more complicated. Note: These functions only work for single-byte character encodings.

 

# POSIX
# chr() - converts decimal value to its ASCII character representation
# ord() - converts ASCII character to its decimal value

chr() {
  [ "$1" -lt 256 ] || return 1
  printf "\\$(printf %o "$1")"
}

Even better to avoid using a subshell is to pass the value inside a variable instead of the command output. faster as it avoids the subshell

chr () {
  local val
  [ "$1" -lt 256 ] || return 1
  printf -v val %o "$1"; printf "\\$val"
  # That one requires bash 3.1 or above.
}

 

ord() {
  # POSIX
  LC_CTYPE=C printf %d "'$1"
}

# hex() - converts ASCII character to a hexadecimal value
# unhex() - converts a hexadecimal value to an ASCII character

hex() {
   LC_CTYPE=C printf %x "'$1"
}

unhex() {
   printf "\\x$1"
}

# examples:

chr "$(ord A)"    # -> A
ord "$(chr 65)"   # -> 65

The ord function above is quite tricky.

  • Tricky? Rather, it's using a feature that I can't find documented anywhere -- putting a single quote in front of a character. Neat effect, but how on earth did you find out about it? Source diving? -- GreyCat

    • It validates The Single Unix Specification: "If the leading character is a single-quote or double-quote, the value shall be the numeric value in the underlying codeset of the character following the single-quote or double-quote." (see printf() to know more) -- mjf

 

Copied from: https://mywiki.wooledge.org/BashFAQ/071

posted on 2020-11-28 15:05  ZhangZhihuiAAA  阅读(34)  评论(0编辑  收藏  举报