40

I have a directory myDir of many .html files. I am trying to create an array of all the files in the directory so I might be able to index the array and be able to refer to particular html files in the directory. I have tried the following line:

myFileNames=$(ls ~/myDir)

for file in $myFileNames; 
#do something

but I want to be able to have a counter variable and have logic like the following:

 while $counter>=0;
   #do something to myFileNames[counter]

I am quite new to shell scripting and am unable to figure out how to achieve this hence would appreciate any help regarding this matter.

0

3 Answers 3

66

You can do:

# use nullglob in case there are no matching files
shopt -s nullglob

# create an array with all the filer/dir inside ~/myDir
arr=(~/myDir/*)

# iterate through array using a counter
for ((i=0; i<${#arr[@]}; i++)); do
    #do something to each element of array
    echo "${arr[$i]}"
done

You can also do this for iteration of array:

for f in "${arr[@]}"; do
   echo "$f"
done
Sign up to request clarification or add additional context in comments.

10 Comments

If you want to limit the number of times the for loop is run you could make the following ammendment: counter=10 for ((i=0; i<${#arr[@]} && i<counter; i++)); do
Actually shopt -s nullglob can be used before array creation to avoid getting any false result.
To match files with txt extension use arr=(~/myDir/*.txt) at top
Then it is better to do cd myDir and then arr=(*.txt)
@HenkPoley: Good point. I have added shopt -s nullglob for this.
|
10

Your solution will work for generating the array. Instead of using a while loop, use a for loop:

#!/bin/bash
files=($( ls * )) #Add () to convert output to array
counter=0
for i in $files ; do
  echo Next: $i
  let counter=$counter+1
  echo $counter
done

3 Comments

Use IFS to set the field separator in this case. So long as IFS doesn't include space, then you should be good.
OP didn't mention this as being part of the criteria :)
You are not supposed to use ls to iterate over files. ls * is redundant, * already means "all the files," and ls * will break if files have spaces in their names.
1
# create an array with all the filer/dir inside ~/myDir
arr=(~/myDir/*)

# iterate through array indexes to get 'counter'
for counter in ${!arr[*]}; do
    echo $counter           # show index
    echo "${arr[counter]}"  # show value
done

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.