journeyxa
journeyxa

Reputation: 11

Creating a file for each character in the ASCII table

I want to make a program which will create files named as characters from the ASCII table. So 128 files from 1 to 127

I did something like this:

    #!/bin/bash

temp=0;

for (( x=0; $x <= 177; x++ )) ; do
    temp=$((temp+1))
    if [ "$temp" = 8 ]; then
    temp=$((0))
    x=$((x+3))
    fi

    echo "$x"

    `touch $'\"$x"'`
done

I know that it's written very weirdly, but what this program does is: counting from 0 to 127 in oct (so from 0 to 177oct). The problem is that touch $'\"$x"' doesn't work properly.

Although touch $'\101' will make a file named "A".

Can anybody help me?

Upvotes: 0

Views: 565

Answers (2)

Benjamin W.
Benjamin W.

Reputation: 52431

This would work:

for num in {0..127}; do
    printf -v fname "\x$(printf '%x' "$num")"
    touch "$fname"
done

Notice that the null character and / are not allowed in a file name.

Here is what this does:

the outer

printf -v fname '\xHH'

stores the byte with the hex value HH (one or two digits) in the variable fname. This gets around the problem where for the value 10 (ASCII newline), command substitution would strip the newline (as it did in the previous revision of this answer), leaving just the empty string.

The inner

printf '%x' "$num"

prints the value of num as a hexadecimal number, which is then used as the HH value of the outer printf.

Say, for example, the value of num is decimal 80. The inner substitution does this:

$ printf '%x' 80
50

So the value of the inner command substitution is 50 (hexadecimal for 80). Now the command becomes

printf -v fname "\x50"

and because of

$ printf "\x50"
P

the next command becomes

touch P

which is what we wanted.

Upvotes: 1

chepner
chepner

Reputation: 531948

bash doesn't provide any particularly simple way to produce a character given an ASCII code point. printf supports converting a decimal value to a hexadecimal representation:

$ printf '%x\n' 65
A

but you need a bash extension to convert a decimal string to a hexadecimal string to use to construct the standard format:

# null characters not allows, start with x=1, not x=0
for ((x=1; x <= 177; x++)); do
    h=$(printf '%x' "$x")  # e.g. 65 -> 41
    c=$(printf "\\x$h")    # e.g. 41 -> A
    [[ $c = "/" ]] && continue  # / is not a valid character for file names
    touch "$c"
done

Note that backquotes are only needed capture the output of the command to use in a larger expression.

Upvotes: 0

Related Questions