The biggest problem with this code is this part:
for i in 'find /home -name *.doc'
You probably think that the variable i
takes the value of each line from the output of the find
command, but this is not the case. Actually the following happens:
The find
command is executed.
The output of the command suffers the effect known as word splitting .
The result of the previous step suffers the effect known as filename expansion .
The resulting elements are used by the for
command to be assigned to the variable i
in their corresponding iteration.
Put another way, the process will fail if any of the file names contain characters that cause filename expansion or word splitting . .
That is, if the output of find
were this:
./archivo 1.doc
./archivo 2.doc
./archivo *.doc
The content of the array would be this (each line is an element of the array):
./archivo
1.doc
./archivo
2.doc
./archivo
archivo 1.doc
archivo 2.doc
archivo *.doc
On the other hand, it is not necessary to manually manage the array indexes. You can use the arreglo+=(elemento)
syntax for Bash to do that work for you.
That said, I can think of at least two methods to deal with this situation.
This is the native method, but it is not as fast or as powerful as find
:
for archivo in "${HOME}"/*.doc; do
arreglo+=( "${archivo}" )
done
shopt -s dotglob globstar
for archivo in "${HOME}"/**/*.doc; do
arreglo+=( "${archivo}" )
done
The first searches for files within the ${HOME}
directory that match the *.doc
pattern. The second does the same but recursively, including hidden directories.
Useful if you prefer to use find
but avoiding the effects of filename expansion , word splitting and the use of for
:
mapfile -t arreglo < <(find "${HOME}" -name '*.doc')
With GNU find
you could even use the -print0
option to avoid problems with line breaks in the file names:
mapfile -d '' -t arreglo < <(find "${HOME}" -name '*.doc' -print0)