Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
208 views
in Technique[技术] by (71.8m points)

ORD and CHR a file in Bash

I build ord and chr functions and they work just fine. But if I take a file that contains , for example:

hello
CHECK THIS HIT
YES

when I ord everything I don't get any new line values. Why is that? I'm writing in Bash.

Here is the code that I am using:

function ord { 
    ordr="`printf "%d
" '$1`" 
}

TEXT="`cat $1`"
for (( i=0; i<${#TEXT}; i++ )) 
do 
    ord "${TEXT:$i:1}" 
    echo "$ordr" 
done
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your ord function is really weird. Maybe it would be better to write it as:

function ord { 
    printf -v ordr "%d" "'$1"
}

Then you would use it as:

TEXT=$(cat "$1")
for (( i=0; i<${#TEXT}; i++ )); do 
    ord "${TEXT:$i:1}" 
    printf '%s
' "$ordr"
done

This still leaves two problems: you won't be able to have null bytes and you won't see trailing newlines. For example (I called your script banana and chmod +x banana):

$ ./banana <(printf 'ab
')
97
98

Two problems show here: the null byte is removed from Bash in the TEXT=$(cat "$1") part, as a Bash variable can't contain null bytes. Moreover, this step also trims trailing newlines.

A more robust approach would be to use read:

while IFS= read -r -n 1 -d '' char; do
    ord "$char"
    printf '%s
' "$ordr"
done < "$1"

With this modification:

$ ./banana <(printf 'ab
')
97
0
98
10

Note that this script will depend on your locale. With my locale (LANG="en_US.UTF-8):

$ ./banana <(printf 'a?
')
97
0
8450
10

whereas:

$ LANG= ./banana <(printf 'a?
')
97
0
226
132
130
10

That's to show you that Bash doesn't read bytes, but characters. So depending on how you want Bash to treat your data, set LANG accordingly.


If your script only does that, it's much simpler to not use an ord function at all:

#!/bin/bash

while IFS= read -r -n 1 -d '' char; do
    printf '%d
' "'$char"
done < "$1"

It's that simple!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...