如何获得类似于linux命令“tree”输出的ASCII字符?

问题描述 投票:0回答:3

有没有办法使用 bash 或 perl 脚本打印 ASCII 字符“├──”和“└──”? 我希望它的输出与“tree”的输出完全相同。

[root@localhost www]# tree -L 1
.
├── cgi-bin
├── error
├── html
└── icons
bash tree
3个回答
5
投票

它们看起来是扩展 ascii 代码的一部分。您可以在这里看到它们 http://www.asciitable.com/

也可以在此处的 Unicode 表中找到:http://unicode-table.com/en/sections/box-drawing/

enter image description here

我相信192、195和196就是你想要的。 采用 Unicode 2501、2514 和 2523。

编辑

发现了一个相关的堆栈问题here,建议用Unicode打印。

你想要的是能够打印unicode,答案就在

perldoc perluniintro
。 您可以使用
\x{nnnn}
,其中 n 是十六进制标识符,或者您可以使用以下名称执行
\N{...}

perl -E 'say "\x{2514}"; use charnames; say "\N{BOX DRAWINGS LIGHT UP AND RIGHT}"'

5
投票

中使用 Unicode 特定字符

这里有3个以上不同的答案...

1.直接在 UTF8 脚本中使用特殊字符。

HorizT='├'
HLine='─'
echo $HorizT$HLine$HLine
├──

2.从输出样本

中查找字符值

当你说

tree
作为输出样本时,你可以运行类似的东西

tree / | sed -ne '2{p;q}'
├── bin

tree / | sed -ne '2{p;q}' | od -An -t o1
342 224 234 342 224 200 342 224 200 040 142 151 156 012

将您的参考输出为八进制值。

知道 Unicode 使用可变的字节数,您的参考字符串包含 3 个 unicode 字符,看起来像 3 组 3 个值,以

342
开头。

所以你可以尝试:

printf "\342\224\234\n"
├

printf -v HorizontalT "\342\224\234"
printf -v Hline "\342\224\200"

echo $HorizontalT$Hline$Hline$Hline
├───

2.b 与 pure bash 相同:

如果您尝试将其剪切并粘贴到终端中:

declare -A shown='()'                  # Array list of already shown characters.
while IFS= read -r line; do                      # For each line in tree output,
    for ((i=0; i<${#line}; i++)); do          # For each character in each line,
        [[ ${line:i:1} == \  ]] && break       # Stop reading line at 1st space!
        if ! [[ -v shown["${line:i:1}"] ]]; then         # If not already shown,
            LANG=C printf -v char %q "${line:i:1}" # Store C printable in $char,
            [[ ${char#\\} == "${line:i:1}" ]] ||    # If printable != character,
                printf 'Char: \47%s\47 => %s\n' "${line:i:1}" "$char"   # print,
            shown["${line:i:1}"]=yes        # Add character to shown array list.
        fi
    done                                                           # Line done,
done < <(tree )    # Done! All this are taking input from tree command's output. 

你必须看到:

Char: '├' => $'\342\224\234'
Char: '─' => $'\342\224\200'
Char: '│' => $'\342\224\202'
Char: ' ' => $'\302\240'
Char: '└' => $'\342\224\224'

备注:

  • 运行此程序时,当前目录必须至少有 1 个子目录,才能显示完整的输出。
  • 执行时间将取决于树的大小! (你可能要等最后一个
    '└'
    ;-)。

3.使用
charmap

搜索特定字符

您可以使用专用的 Unicode 浏览器,例如

Debian Gnome GNU/Linux
下的 charmap:

浏览并找到您的角色,然后在第二个选项卡上:

Character Details

您可以阅读各种有用的表示

->
八进制转义

printf '\342\224\234\n'
├

3+。使用
printf

打印 Unicode 字体

一旦你知道了unicode值,你就可以使用

printf
来创建变量:

printf -v char '\U251C'
echo $char
├

从那里开始,经过一番头脑风暴:

string=
for i in 0 2 16 24 {12..60..8} ;do
    printf -v r '\\U25%02X' $i
    printf -v char "$r"
    string+="$char "
done
echo "$string"
─ │ ┐ ┘ ┌ └ ├ ┤ ┬ ┴ ┼ 

或者

string=
for i in {80..108} ;do
    printf -v r '\\U25%02X' $i
    printf -v char "$r"
    string+="$char "
done
echo "$string"
═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟ ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ 

4.最终
bash
功能

严格回应SO要求:

我希望它与“tree”的输出完全相同。

这是一个函数:

tree-L1() { 
    local _i indent=0 entry root=${1:-.};
    local -i dirs files;
    [[ $1 == -i ]] && indent=$2 && shift 2;
    echo "$root";
    . <(cd "$root";set -- *;echo ${@@A});
    printf -v indent '%*s' "$indent" '';
    for ((_i=1; _i<=$#; _i++))
    do
        entry=${!_i};
        [[ -d $root/$entry ]] && dirs+=1 || files+=1;
        [[ -L $root/$entry ]] && printf -v entry '%s -> %s' "${!_i}" "$(
            readlink "$root/${!_i}")";
        if ((_i==$#)); then
            printf '%b%b%b%b %s\n' "${indent// /\\U2502   }" \
                \\U2514 \\U2500{,} "$entry";
        else
            printf '%b%b%b%b %s\n' "${indent// /\\U2502   }" \
                \\U251C \\U2500{,} "$entry";
        fi;
    done;
    printf '\n%d directories, %d files\n' $dirs $files
}

那么你可以尝试比较一下:

diff <(tree-L1 /etc) <(tree -L 1 /etc)

可能不会输出任何内容,因为没有差异!或者

diff --width 80 -y <(tree-L1 /etc) <(tree -L 1 /etc)

5.按 字符名称

浏览 Unicode 表

请看一下有(linux)终端字符选择器吗?在 SuperUser 上,我发布了一个小小的 Python unicode 库:

./dumpUnicode | grep 'BOX DRAWINGS LIGHT.*\(HORI\|VERT\)'
\U002500: '─' BOX DRAWINGS LIGHT HORIZONTAL
\U002502: '│' BOX DRAWINGS LIGHT VERTICAL
\U002504: '┄' BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
\U002506: '┆' BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
\U002508: '┈' BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
\U00250A: '┊' BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
\U00251C: '├' BOX DRAWINGS LIGHT VERTICAL AND RIGHT
\U002524: '┤' BOX DRAWINGS LIGHT VERTICAL AND LEFT
\U00252C: '┬' BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
\U002534: '┴' BOX DRAWINGS LIGHT UP AND HORIZONTAL
\U00253C: '┼' BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
\U00254C: '╌' BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL
\U00254E: '╎' BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL
\U01FBAF: '🮯' BOX DRAWINGS LIGHT HORIZONTAL WITH VERTICAL STROKE

5+ 从
tree
输出中提取特殊字符,并带有完整描述

使用之前的脚本,首先创建一个 关联数组

u8Table
:

declare -A u8Table='()'
while IFS=\  read -r cod char dsc; do
    char="${char#\'}" char="${char%\'}"
    u8Table["$char"]="$cod $dsc"
done < <(dumpUnicode | grep -v '^.U0000[2-7]')

然后

declare -A shown='()'
while IFS= read -r line; do
    for ((i=0; i<${#line}; i++)); do
        [[ ${line:i:1} == \  ]] && break
        if ! [[ -v shown["${line:i:1}"] ]]; then
            LANG=C printf -v char %q "${line:i:1}"
            [[ ${char#\\} == "${line:i:1}" ]] ||
                 printf 'Char: \47%s\47 => %-16s %s\n' \
                     "${line:i:1}" "$char" "${u8Table["${line:i:1}"]}"
            shown["${line:i:1}"]=yes
        fi
    done
done < <(tree)
Char: '├' => $'\342\224\234'  \U00251C: BOX DRAWINGS LIGHT VERTICAL AND RIGHT
Char: '─' => $'\342\224\200'  \U002500: BOX DRAWINGS LIGHT HORIZONTAL
Char: '│' => $'\342\224\202'  \U002502: BOX DRAWINGS LIGHT VERTICAL
Char: ' ' => $'\302\240'      \U0000A0: NO-BREAK SPACE
Char: '└' => $'\342\224\224'  \U002514: BOX DRAWINGS LIGHT UP AND RIGHT

4
投票
echo -e "\0342\0224\0224\0342\0224\0200\0342\0224\0200 \033[01"
© www.soinside.com 2019 - 2024. All rights reserved.