So, I've a simple nested loop where the outer for
loops over all the files in a directory and the inner for
loops over all characters of these filenames.
#!/bin/bash
if [ $# -lt 1 ]
then
echo "Please provide an argument"
exit
fi
for file in ls $1
do
for ch in $file
do
echo $ch
done
done
The script above doesn't work. The inner loop doesn't loop over all the characters in the filename but instead loops over the entire thing.
UPDATE:
Based on @ilkkachu's answer I was able to come up with the following script and it works as expected. But I was curious can we not use the for...in
loop to iterate over strings?
#!/bin/bash
if [ $# -lt 1 ]
then
echo "Please provide an argument"
exit
fi
for file in ls $1
; do
for ((i=0; i<${#file}; i++)); do
printf "%q\n" "${file:i:1}"
done
done
ls
to gather a list of files for scripted usage! https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-to-do-instead – Marcus Müller Jul 04 '21 at 15:57ls
for that; that's bad.for file in "$1"/*
just works. – Marcus Müller Jul 06 '21 at 11:16ls
. It isn't needed here and it just makes your script less likely to work. ilkkachu gave you a version withoutls
, so use that! For more details on why parsingls
is bad, see: https://mywiki.wooledge.org/ParsingLs – terdon Jul 06 '21 at 12:56