Calibre
Calibre

Reputation: 13

For loop knocking me for a loop. Whitespaces, new lines, unexpected behavior

I'm trying to teach myself bash and decided to try some simple loops. I made a script that prints a numbered list of the files in a directory along with their character count using different loops, which I put into functions just so I can comment/uncomment the function calls instead of the entire loops, like so:

function filelist { find . -maxdepth 1 -type f | sort -bdf; }
filecount=$(filelist | wc -l)

function until_loop {
                    i=1; until [ $i -gt "$filecount" ]; do
                        <do stuff>
                    done; echo ""
                    }

function while_loop {
                    i=1; while [ $i -le "$filecount" ]; do
                        <do stuff>
                    done; echo ""
                    }

function while_read_loop {
                    i=1; echo $(filelist) > /tmp/filelist.txt
                    while read line; do
                       <do stuff>
                    done < /tmp/filelist.txt; echo ""
                    }

function for_loop_1 {
                    i=1; for i in $(seq 1 "$filecount"); do
                         <do stuff>
                    done; echo ""
                    }

function for_loop_2 {
                    for ((i=1;i<=filecount;i++)); do
                        <do stuff>
                    done; echo ""
                    }

echo "List generated from an \"Until\" loop:"; until_loop

echo "List generated from a \"While\" loop:"; while_loop

echo "List generated from a \"While read\" loop:"; while_read_loop

echo "List generated from a \"For\" loop (method) 1:"; for_loop_1

echo "List generated from a \"For\" loop (method 2):"; for_loop_2

The contents of each loop are the same (except for specific parts such as not needing to increment the value of i in the body of for_loop_2).

All of these loops give the same output, except for for_loop_1, which throws a strange sed error and seems to be printing all of the file numbers as a single word.

Here's the complete loop:

i=1; for i in $(seq 1 "$filecount"); do
   linetext=$( filelist | sed -n ${i}p ); linetext=${linetext:2}
   charactercount="$(cat "$(filelist | sed -n "${i}p")" | wc -m)"
   printf "%02d" "$i" && printf ". The file "$linetext" has "$charactercount" characters.\n"
   i=$((i+1))
done; echo ""

And here are the outputs:

#Everyone else:

01. The file aa-shader-4.0-level2.slangp has 348 characters.
02. The file aa-shader-4.0.slangp has 186 characters.
03. The file advanced-aa.slangp has 318 characters.
04. The file fxaa.slangp has 98 characters.
05. The file reverse-aa.slangp has 106 characters.
06. The file smaa+linear.slangp has 600 characters.
07. The file smaa+sharpen.slangp has 996 characters.
08. The file smaa.slangp has 828 characters.

#for_loop_1

cat: 30: No such file or directory
01. The file aa-shader-4.0-level2.slangp has  characters.
cat: 23: No such file or directory
02. The file aa-shader-4.0.slangp has  characters.
cat: 21: No such file or directory
03. The file advanced-aa.slangp has  characters.
cat: 14: No such file or directory
04. The file fxaa.slangp has  characters.
cat: 20: No such file or directory
05. The file reverse-aa.slangp has  characters.
cat: 21: No such file or directory
06. The file smaa+linear.slangp has  characters.
cat: 22: No such file or directory
07. The file smaa+sharpen.slangp has  characters.
cat: 14: No such file or directory
08. The file smaa.slangp has  characters.
/home/user/Scripts/list_character_count.sh: line 48: 08: value too great for base (error token is "08")

#for_loop_1 with either IFS= or IFS="" set

sed: -e expression #1, char 3: unknown command: `
'
cat: 0: No such file or directory
sed: -e expression #1, char 3: unknown command: `
'
01
02
03
04
05
06
07
08. The file  has  characters.
/home/user/Scripts/list_character_count.sh: line 48: 01
02
03
04
05
06
07
08: syntax error in expression (error token is "02
03
04
05
06
07
08")

Line 44 is i=$((i+1)). There isn't a single `' or `(some newline character)' in the entire script. I don't know where cat is even getting those numbers. Honestly, I just don't know enough to even understand this simple error message, which is quite frustrating. I'm pretty sure the issue has to do with whitespaces, but that's as far as I got.

I tried using sed '${i}!d' instead of sed -n "${i}p", I tried using grep instead, I tried setting IFS= and IFS="", but whatever I do, it always works in the other loops but never in for_loop_1. I read the bash documentation and searched here and on DuckDuckGo but didn't find an explanation. Could someone shed some light? Please and thank you, and sorry for my code which is probably very ugly and full of rookie mistakes.

While I'm here, I have another, much simpler question: Why is it that i=$((i+1)) works but not i++ or i+=1? Using i++ in the first line of the second for loop works fine.

Upvotes: 0

Views: 22

Answers (0)

Related Questions