あなたの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
これにはまだ 2 つの問題が残っています。null バイトを持つことができず、末尾の改行が表示されません。例(私はあなたのスクリプトbanana
と呼んだchmod +x banana
):
$ ./banana <(printf 'a\0b\n')
97
98
TEXT=$(cat "$1")
ここでは 2 つの問題が示されています。Bash 変数には null バイトを含めることができないため、この部分でBash から null バイトが削除されています。さらに、このステップでは末尾の改行も削除されます。
より堅牢なアプローチは、次を使用すること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 がバイトではなく文字を読み取ることを示しています。したがって、Bash でデータをどのように処理するかに応じて、それに応じて設定してくださいLANG
。
ord
スクリプトがそれを行うだけの場合は、関数をまったく使用しない方がはるかに簡単です。
#!/bin/bash
while IFS= read -r -n 1 -d '' char; do
printf '%d\n' "'$char"
done < "$1"
それはとても簡単です!