Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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
Arrays 目录中除一个以外的所有文件的数组_Arrays_Bash - Fatal编程技术网

Arrays 目录中除一个以外的所有文件的数组

Arrays 目录中除一个以外的所有文件的数组,arrays,bash,Arrays,Bash,正在尝试找出如何包含所有.txt文件,除了名为manifest.txt的文件 FILES=(path/to/*.txt) 您可以一次生成一个文件,避免生成不需要的文件: declare -a files=() for file in /path/to/files/* do ! [[ -e "$file" ]] || [[ "$file" = */manifest.txt ]] || files+=("$file") done 请注意,for语句中的globbing不会导致文件名中的空白

正在尝试找出如何包含所有
.txt
文件,除了名为
manifest.txt
的文件

FILES=(path/to/*.txt) 

您可以一次生成一个文件,避免生成不需要的文件:

declare -a files=()
for file in /path/to/files/*
do
  ! [[ -e "$file" ]] || [[ "$file" = */manifest.txt ]] || files+=("$file")
done
请注意,
for
语句中的globbing不会导致文件名中的空白(甚至换行)问题

编辑

我添加了一个文件存在性测试,以处理glob失败且未设置
nullglob
选项的情况。

您可以使用以下方法:

shopt -s extglob
files=(path/to/!(manifest).txt)
!(模式列表)
模式匹配“除一个给定模式外的任何其他模式”

请注意,这完全排除了
manifest.txt
和其他内容<例如,code>mmanifest.txt仍然会进入数组



作为旁注:完全不匹配的glob会扩展到自身(请参见和)。使用
nullglob
(扩展为空字符串)和
failglob
(打印错误消息)shell选项可以更改此行为。

我认为最好使用关联数组来处理此问题,即使只有一个元素

考虑:

$ touch f{1..6}.txt manifest.txt
$ ls *.txt
f1.txt      f3.txt      f5.txt      manifest.txt
f2.txt      f4.txt      f6.txt
可以为要排除的名称创建关联数组:

declare -A exclude 
for f in f1.txt f5.txt manifest.txt; do 
    exclude[$f]=1
done
然后将文件添加到不在关联数组中的数组:

files=()
for fn in *.txt; do
    [[ ${exclude[$fn]} ]] && continue
    files+=("$fn")  
done

$ echo "${files[@]}"
f2.txt f3.txt f4.txt f6.txt

这种方法允许从文件列表中排除任意数量的内容

如果文件名中有空格和/或通配符(这是完全合法的),这仍然不起作用。尝试
touch“this*is*a*file.txt”manifest.txt
,然后使用它,然后查看
文件
数组包含的内容。@GordonDavisson,它可以工作,即使我使用
touch
命令创建此文件。请更正您的示例或解释。@GrzegorzGórkiewicz在空目录中运行我的
touch
命令,然后运行您的命令(在
$PWD/*.txt
),然后运行
printf“'%s'”${FILES[@]}
为我提供了
'/Users/gordon/tmp/manifest.txt'/Users/gordon/tmp/this''manifest.txt''这*是*a*文件.txt''是*manifest.txt''这*是*a*文件.txt''文件.txt'
。这仍然扩展了通配符。您必须引用
$()
来防止出现这种情况,但这样一来,您将得到一个只包含一个元素的数组。@GrzegorzGórkiewicz您测试过我的示例吗?最新的更新仍然失败(尽管稍微不那么严重)。另外,请阅读上的BashFAQ项目。在我做的一个小测试中,它对我不起作用。我得到一个包含
的数组!(manifest).txt
我想除了
extglob
,您还需要
nullglob
。@Fred看起来您没有打开
extglob
?请注意,它可以在交互式shell中打开,但在非交互式shell中关闭,以防您在脚本中尝试此操作<代码>空glob是不需要的,我想说。@BenjaminW。我可以确认我已经在一个交互式shell中复制了它。只需禁用
nullglob
(没有其他更改),我就可以从预期的结果转换到我的评论中描述的结果。@Fred,在您根本没有任何
.txt
文件的情况下?“这是我能得到你所描述的东西的唯一途径。”本杰明。是,否
.txt
文件;也许这个案子应该明确处理?
files=()
for fn in *.txt; do
    [[ ${exclude[$fn]} ]] && continue
    files+=("$fn")  
done

$ echo "${files[@]}"
f2.txt f3.txt f4.txt f6.txt