Arrays bash:筛选文件列表,其中可以包含空格";-需要关联数组吗?

Arrays bash:筛选文件列表,其中可以包含空格";-需要关联数组吗?,arrays,bash,Arrays,Bash,我想创建一个文件名列表-其中可能有一些带有空格的文件名。 此列表应在bash中过滤(不使用“查找”本身或类似内容)。 必须以某种方式处理最终列表。 我无法使其工作-除非使用关联数组 这是我的解决办法 测试目录: > find $HOME/test-dir/ /home/frank/test-dir/ /home/frank/test-dir/FileA /home/frank/test-dir/File D /home/frank/test-dir/FileC /home/frank/te

我想创建一个文件名列表-其中可能有一些带有空格的文件名。
此列表应在bash中过滤(不使用“查找”本身或类似内容)。
必须以某种方式处理最终列表。
我无法使其工作-除非使用关联数组

这是我的解决办法

测试目录:

> find $HOME/test-dir/
/home/frank/test-dir/
/home/frank/test-dir/FileA
/home/frank/test-dir/File D
/home/frank/test-dir/FileC
/home/frank/test-dir/FileB
剧本#1(作品):

对于“文件D”,任何使用纯数组的尝试都会失败。 我可以填充数组,但遍历或尝试删除元素会再次破坏它:

脚本#2(不起作用):

有趣的是,删除IFS的恢复(参见上面的注释行)会导致

输出:

> ./test2.sh 
/home/frank/test-dir/FileA
/home/frank/test-dir/File
D
/home/frank/test-dir/FileC
/home/frank/test-dir/FileB

/home/frank/test-dir/FileA
/home/frank/test-dir/File
D
/home/frank/test-dir/FileB
> ./test2.sh 
/home/frank/test-dir/FileA
/home/frank/test-dir/File D
/home/frank/test-dir/FileC
/home/frank/test-dir/FileB

/home/frank/test-dir/FileA
/home/frank/test-dir/File D
/home/frank/test-dir/FileB
但是我想本地化IFS的设置,使其不干扰旧代码,这取决于不同的IFS值

如何使其与纯数组(非关联数组)一起工作

附录

这也适用于:

> cat test2b.sh 
#!/bin/bash

readarray -t Data < <(find $HOME/test-dir/ -type f)

while read Value
do
    echo "$Value"
done < <(IFS=$'\n'; for Value in ${Data[@]}; do echo $Value; done)
echo

# remove #1 element via variable
Del=2
unset 'Data[$Del]'

while read Value 
do
    echo "$Value"
done < <(IFS=$'\n'; for Value in ${Data[@]}; do echo $Value; done)
echo
>cat test2b.sh
#!/bin/bash

readarray-t Data<考虑使用“printf”将数组转换为新的行分隔值。更紧凑,并且不会被以“-”开头的文件名所欺骗(看起来像选项)

读取值时
做
回显“$Value”

完成<我给你的建议如下:

  • 使用
    find
    列出文件并在
    while
    循环中处理它们
  • find
    打印文件名,后跟空字符,而不是换行符
  • 在循环中进行选择
这看起来像这样:

#/usr/bin/env bash
del=2
计数器=0
在读取-d$'\0'文件时查找$HOME/test dir/-type f-print0;做
#忽略元素
((计数器++==del))&继续(&C)
#行动
回显“$file”
完成

问题的原因是您没有使用双精度包装
${Data[@]}
循环中的引号。然后将数组
${Data[@]}
扩展为 违反您意愿的IFS分裂词列表。
此外,您不需要为
readarray
临时将IFS分配到换行符

然后
script2
将如下所示:

readarray -t Data < <(find $HOME/test-dir/ -type f)

for Value in "${Data[@]}"
do
    echo "$Value"
done
echo

# remove an element via variable
Del=2
unset 'Data[$Del]'

for Value in "${Data[@]}"
do
    echo "$Value"
done
while IFS= read -r -d "" f; do
    Data+=("$f")
done < <(find $HOME/test-dir/ -type f -print0)
如果
readarray
支持
-d
选项(bash>=4.4),您也可以说:

readarray -t -d "" Data < <(find $HOME/test-dir/ -type f -print0)

readarray-t-d”Datawhile read Value 
do
    echo "$Value"
done < <(printf '%s\n' "${Data[@]}" )
readarray -t Data < <(find $HOME/test-dir/ -type f)

for Value in "${Data[@]}"
do
    echo "$Value"
done
echo

# remove an element via variable
Del=2
unset 'Data[$Del]'

for Value in "${Data[@]}"
do
    echo "$Value"
done
while IFS= read -r -d "" f; do
    Data+=("$f")
done < <(find $HOME/test-dir/ -type f -print0)
readarray -t -d "" Data < <(find $HOME/test-dir/ -type f -print0)