Reading filenames into an array

I want to get a list of files and then read the results into an array where each array element corresponds to a file name. Is this possible?

99448 次浏览

Following will create an array arr with ls output in current directory:

arr=( $(ls) )

Though using output of ls is not safe at all.

Much better and safer than ls you can use echo *:

arr=( * )


echo ${#arr[@]} # will echo number of elements in array


echo "${arr[@]}" # will dump all elements of the array

Don't use ls, it's not intended for this purpose. Use globbing.

shopt -s nullglob
array=(*)
array2=(file*)
array3=(dir/*)

The nullglob option causes the array to be empty if there are no matches.

Actually, ls isn't the way to go. Try this:

declare -a FILELIST
for f in *; do
#FILELIST[length_of_FILELIST + 1]=filename
FILELIST[${#FILELIST[@]}+1]=$(echo "$f");
done

To get a filename from the array use:

echo ${FILELIST[x]}

To get n filenames from the array starting from x use:

echo ${FILELIST[@]:x:n}

For a great tutorial on bash arrays, see: http://www.thegeekstuff.com/2010/06/bash-array-tutorial/

Try this,

path="" # could set to any absolute path
declare -a array=( "${path}"/* )

I'm assuming you'll pull out the unwanted stuff from the list later.

In bash you can create an array of filenames with pathname expansion (globbing) like so:

#!/bin/bash
SOURCE_DIR=path/to/source
files=(
"$SOURCE_DIR"/*.tar.gz
"$SOURCE_DIR"/*.tgz
"$SOURCE_DIR"/**/*
)

The above will create an array called files and add to it N array elements, where each element in the array corresponds to an item in SOURCE_DIR ending in .tar.gz or .tgz, or any item in a subdirectory thereof with subdirectory recursion possible as Dennis points out in the comments.

You can then use printf to see the contents of the array including paths:

printf '%s\n' "${files[@]}" # i.e. path/to/source/filename.tar.gz

Or using parameter substitution to exclude the pathnames:

printf '%s\n' "${files[@]##*/}" # i.e. filename.tgz

If you need a more specific file listing that cannot be returned through globbing, then you can use process substitution for the find command with a while loop delimited with null characters.

Example:

files=()
while IFS= read -r -d $'\0' f; do
files+=("$f")
done < <(find . -type f -name '*.dat' -size +1G -print0)