Reading filenames into an array

BashUnixCygwin

Bash Problem Overview


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?

Bash Solutions


Solution 1 - Bash

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.

Solution 2 - Bash

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

Solution 3 - Bash

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

Solution 4 - Bash

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/][1]

[1]: http://www.thegeekstuff.com/2010/06/bash-array-tutorial/ "bash array tutorial"

Solution 5 - Bash

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.

Solution 6 - Bash

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)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondublintechView Question on Stackoverflow
Solution 1 - BashDennis WilliamsonView Answer on Stackoverflow
Solution 2 - BashanubhavaView Answer on Stackoverflow
Solution 3 - BashvhsView Answer on Stackoverflow
Solution 4 - BashxizdaqrianView Answer on Stackoverflow
Solution 5 - BashKSU_PhysicsView Answer on Stackoverflow
Solution 6 - BashStephanView Answer on Stackoverflow