ORD и CHR файл в Bash
Я строю ord
а также chr
функции, и они работают просто отлично. Но если я возьму файл, который содержит \n
, например:
hello
CHECK THIS HIT
YES
когда я ord
все, что я не получаю никаких новых значений строки. Это почему? Я пишу на Bash.
Вот код, который я использую:
function ord {
ordr="`printf "%d\n" \'$1`"
}
TEXT="`cat $1`"
for (( i=0; i<${#TEXT}; i++ ))
do
ord "${TEXT:$i:1}"
echo "$ordr"
done
1 ответ
Ваш 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 читает не байты, а символы. Поэтому в зависимости от того, как вы хотите, чтобы Bash обрабатывал ваши данные, установите LANG
соответственно.
Если ваш скрипт только это делает, гораздо проще не использовать ord
функция вообще:
#!/bin/bash
while IFS= read -r -n 1 -d '' char; do
printf '%d\n' "'$char"
done < "$1"
Это так просто!