有没有办法使用 bash 或 perl 脚本打印 ASCII 字符“├──”和“└──”? 我希望它的输出与“tree”的输出完全相同。
[root@localhost www]# tree -L 1
.
├── cgi-bin
├── error
├── html
└── icons
它们看起来是扩展 ascii 代码的一部分。您可以在这里看到它们 http://www.asciitable.com/
也可以在此处的 Unicode 表中找到:http://unicode-table.com/en/sections/box-drawing/
我相信192、195和196就是你想要的。 采用 Unicode 2501、2514 和 2523。
编辑
发现了一个相关的堆栈问题here,建议用Unicode打印。
。 您可以使用perldoc perluniintro
,其中 n 是十六进制标识符,或者您可以使用以下名称执行\x{nnnn}
:\N{...}
perl -E 'say "\x{2514}"; use charnames; say "\N{BOX DRAWINGS LIGHT UP AND RIGHT}"'
这里有3个以上不同的答案...
HorizT='├'
HLine='─'
echo $HorizT$HLine$HLine
├──
当你说
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
├───
如果您尝试将其剪切并粘贴到终端中:
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'
备注:
'└'
;-)。charmap
您可以使用专用的 Unicode 浏览器,例如
Debian Gnome GNU/Linux下的
charmap
:
浏览并找到您的角色,然后在第二个选项卡上:
Character Details
:
您可以阅读各种有用的表示
->
八进制转义:
printf '\342\224\234\n'
├
printf
一旦你知道了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"
═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟ ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬
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)
请看一下有(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
tree
输出中提取特殊字符,并带有完整描述使用之前的脚本,首先创建一个 bash 关联数组
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
echo -e "\0342\0224\0224\0342\0224\0200\0342\0224\0200 \033[01"