如何使用 bash/shell/zsh 将字符串中的所有 UTF8 Unicode 字符转换为其相关的代码点?

How can I convert all UTF8 Unicode characters in a string to their relevant Codepoints using bash/shell/zsh?

似乎有很多关于将 'Codepoints' 转换为 utf8 的问题,但我无法在任何地方找到相反的答案。

我想要 运行 一个脚本,它将 My 之类的字符串转换为 MyU+1F4D4

我试过这样的事情:DECODEDSTRING=$(echo "My" | iconv -f utf-8 -t ASCII//TRANSLIT)但我似乎无法弄清楚需要什么。

提前致谢。

使用 perl,在任何 shell 中工作,只要参数以 UTF-8 编码:

$ perl -CA -E 'for my $arg (@ARGV) { say map { my $cp = ord; $cp > 127 ? sprintf "U+%04X", $cp : $_ } split //, $arg }' "My"
MyU+1F4D4

Non-ASCII 代码点打印为 U+XXXX(0 填充,如果需要更多十六进制数字),ASCII 码点打印为 human-readable 个字母。


或者为了达到最大速度,一个 C 程序也能做到:

// Compile with: gcc -o print_unicode -std=c11 -O -Wall -Wextra print_unicode.c                                                                                                                                                                                 
#include <assert.h>
#include <inttypes.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uchar.h>

#if __STDC_VERSION__ < 201112L
#error "Need C11 or newer"
#endif
#ifndef __STDC_UTF_32__
#error "Not using Unicode"
#endif

int main(int argc, char **argv) {
  // arguments should be encoded according to locale's character set
  setlocale(LC_CTYPE, ""); 

  for (int i = 1; i < argc; i++) {
    char *s = argv[i];
    size_t len = strlen(argv[i]);
    mbstate_t state;
    memset(&state, 0, sizeof state);

    while (len > 0) {
      char32_t c;
      size_t rc = mbrtoc32(&c, s, len, &state);
      assert(rc != (size_t)-3);
      if (rc == (size_t)-1) {
        perror("mbrtoc32");
        return EXIT_FAILURE;
      } else if (rc == (size_t)-2) {
        fprintf(stderr, "Argument %d is incomplete!\n", i);
        return EXIT_FAILURE;
      } else if (rc > 0) {
        if (c > 127) {
          printf("U+%04" PRIXLEAST32, c);
        } else {
          putchar((char)c);
        }
        s += rc;
        len -= rc;
    }
    putchar('\n');
  }
  return 0;
}
$ ./print_unicode "My"
MyU+1F4D4