你的ord
功能真的很奇怪。也许最好把它写成:
function ord {
printf -v ordr "%d" "'$1"
}
然后你会用它作为:
TEXT=$(cat "$1")
for (( i=0; i<${#TEXT}; i++ )); do
ord "${TEXT:$i:1}"
printf '%s\n' "$ordr"
done
这仍然留下了两个问题:您将无法拥有空字节并且您将看不到尾随的换行符。例如(我调用了你的脚本banana
和chmod +x banana
):
$ ./banana <(printf 'a\0b\n')
97
98
这里显示了两个问题:在部分中从 Bash 中删除了空字节TEXT=$(cat "$1")
,因为 Bash 变量不能包含空字节。此外,此步骤还修剪尾随换行符。
更强大的方法是使用read
:
while IFS= read -r -n 1 -d '' char; do
ord "$char"
printf '%s\n' "$ordr"
done < "$1"
通过此修改:
$ ./banana <(printf 'a\0b\n')
97
0
98
10
请注意,此脚本将取决于您的语言环境。使用我的语言环境(LANG="en_US.UTF-8
):
$ ./banana <(printf 'a\0ℂ\n')
97
0
8450
10
然而:
$ LANG= ./banana <(printf 'a\0ℂ\n')
97
0
226
132
130
10
这是为了向您展示 Bash 不读取bytes,而是characters。因此,根据您希望 Bash 如何处理您的数据,进行LANG
相应的设置。
ord
如果您的脚本只这样做,那么根本不使用函数要简单得多:
#!/bin/bash
while IFS= read -r -n 1 -d '' char; do
printf '%d\n' "'$char"
done < "$1"
就是这么简单!