74

我想获取一个文件列表,然后将结果读入一个数组,其中每个数组元素对应一个文件名。这可能吗?

4

6 回答 6

122

不要使用ls,它不是用于此目的。使用通配符。

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

nullglob如果没有匹配项,该选项会导致数组为空。

于 2012-06-11T13:53:40.937 回答
32

以下将在当前目录中创建一个带有 ls 输出的数组 arr:

arr=( $(ls) )

尽管使用的输出ls根本不安全。

ls您可以使用的更好、更安全echo *

arr=( * )

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

echo "${arr[@]}" # will dump all elements of the array
于 2012-06-11T13:53:23.367 回答
3

在 bash 中,您可以使用路径名扩展(通配符)创建一个文件名数组,如下所示:

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

上面将创建一个名为的数组files并向其添加 N 个数组元素,其中数组中的每个元素对应于以orSOURCE_DIR结尾的项目,或者其子目录中的任何项目,如丹尼斯在评论中指出的那样,子目录递归可能。.tar.gz.tgz

然后,您可以使用printf来查看数组的内容,包括路径:

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

或者使用参数替换来排除路径名:

printf '%s\n' "${files[@]##*/}" # i.e. filename.tgz
于 2018-08-04T07:53:35.080 回答
2

其实,ls也不是办法。尝试这个:

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

要从数组中获取文件名,请使用:

echo ${FILELIST[x]}

要从从 x 开始的数组中获取 n 个文件名,请使用:

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

有关 bash 数组的精彩教程,请参阅: http ://www.thegeekstuff.com/2010/06/bash-array-tutorial/

于 2012-06-12T03:45:00.703 回答
1

尝试这个,

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

我假设您稍后会从列表中取出不需要的东西。

于 2016-07-15T19:03:42.550 回答
0

如果您需要一个无法通过通配符返回的更具体的文件列表,那么您可以使用进程替换来使用以空字符分隔find的循环来替换命令。while

例子:

files=()
while IFS= read -r -d $'\0' f; do
    files+=("$f")
done < <(find . -type f -name '*.dat' -size +1G -print0)
于 2021-10-23T22:18:37.693 回答