Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 将文件名读入数组_Bash_Unix_Cygwin - Fatal编程技术网

Bash 将文件名读入数组

Bash 将文件名读入数组,bash,unix,cygwin,Bash,Unix,Cygwin,我想得到一个文件列表,然后将结果读入一个数组,其中每个数组元素对应一个文件名。这可能吗?以下内容将在当前目录中创建具有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 不要使用l

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

以下内容将在当前目录中创建具有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

不要使用
ls
,它是用于此目的的。使用globbing

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

如果不存在匹配项,
nullglob
选项会导致数组为空。

实际上,
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阵列的详细教程,请参见: 试试这个

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

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

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

上面将创建一个名为
files
的数组,并向其中添加N个数组元素,其中数组中的每个元素对应于
SOURCE_DIR
中的一个项目,以
.tar.gz
.tgz
结尾,或其子目录中的任何项目,其子目录递归可能如注释中的Dennis

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

printf '%s\n' "${files[@]}" # i.e. path/to/source/filename.tar.gz
或使用参数替换排除路径名:

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

是的,这是可能的。如果名称可能包含任意字符(名称中的空格和换行符会导致悲伤),则可能不建议这样做,但这是可行的。您对手册的哪一部分理解有困难?
ls
不是必需的,不应该用于此目的。同意,我只是想告诉您如何从一些命令输出创建数组。但是,我编辑了我的回答,强调应该避免输出
ls
。当数组扩展没有被引用时,数组的所有元素都表示为字符串,而不是数组的单个元素。无引号的
${arr[*]}
${arr[@]}
是相同的。有人知道数组可以容纳的最大文件名/元素数吗?anubhava,请删除
arr=($(ls))
行。或者,如果你想留下它,请明确添加一个类似“不要这样做,它坏了”。谢谢,还有什么我可以用管道传递这些结果的吗?我尝试了类似于arr(*grep.txt)的东西,但它不喜欢。@dublintech:您不需要
grep
,只需在glob中包含字符串:
array=(*.txt)
array=(*foo*)
您也可以将其添加到数组,您应该在文件glob上迭代,或者像我的回答中那样使用文件glob创建一个数组,而不是两者都是!。向数组中添加元素时,没有理由在复杂索引表达式中使用数组的长度(首先,如果数组是稀疏的,它将无法按预期工作)<代码>数组+=(元素)。没有理由使用
$(echo“$f”)
直接完成作业即可。您的一条
echo
语句上缺少一个右大括号。您是否知道,您所做的只是以一种不正确的方式执行
FILELIST=(*)
?(或者,更确切地说是
FILELIST+=(*)
)。你到底为什么要使用
$(echo“$f”)
而不是只使用
“$f”
?你需要
shopt-s globstar
才能使用递归全局搜索(
**
),我不需要。MacOS上的默认Bash是3.2,它没有
globstar
。使用
echo/usr/**/|wc-c
输出对某些目录名中的字符进行计数有什么帮助?在我的Mac电脑上,在Sierra中使用Bash 3.2,或在Bash 4.4中关闭
globstar
时,它输出122。如果在启用
globstar
的情况下运行bash4.4,则得到277904。后者显然是递归的,而前者不是。顺便说一句,
shopt
是定义的,但我想你的意思是
globstar
(在Bash 3.2中,
shopt-p globstar
给出了一个错误,在Bash 4.4中它显示它是设置的还是未设置的)。
hash
仅适用于外部可执行文件(尝试
hash-tls
帮助hash
)并且不会为
shopt
显示任何内容,因为它是内置的,或者为
globstar
显示任何内容,因为它是一个选项而不是一个可执行文件。尝试
键入-a shopt
以显示
shopt
的来源,并尝试
shopt
自身显示所有选项的设置。使用
echo“$BASH\u VERSION”
显示当前运行的shell的版本(如果是BASH),并查看
ps-o tty的输出,command
查看它是否实际是
/bin/BASH
。比较
find/usr-type d | wc-l
echo/usr/**/|tr-cd”“| wc-c
。。。。。。如果递归全局搜索有效,则计数应该相当接近。我的计数在3800左右。我可以把它留在这里。这并不特定于OP的问题,但在输出文件名/路径时,它是一种有用的技术。
printf '%s\n' "${files[@]##*/}" # i.e. filename.tgz