在 bash 中处理数组值

erc*_*rch 3 bash array

我正在尝试根据文件名创建一个数组,但遇到空格问题。这似乎很常见。但是 - 据我所知 - 引号设置正确,我想这一定是数组的构建方式。

to_dump="$(find . -maxdepth 1 -print0 )"
to_dump_array=($to_dump)

read -p " ->  " final
case "$final" in
   a) for drop in "${to_dump_array[@]}" ;
      do cp "$drop" --recursive --force Destination_Folder && \
      echo "dropped \"$drop\" ;
      done ;;
   b) echo "Won't drop anything" ;;
esac
Run Code Online (Sandbox Code Playgroud)

我想应该有更好的方法来从查找查询构建数组。另外,我还有哪里错了?

Sco*_*der 7

-print0不应在$(...)替换中使用,因为 bash 变量中的字符串以空字符结尾。

我问了一个问题,其答案与这个问题的要求相似:https : //stackoverflow.com/a/30469553/1091693

将该答案调整为您的问题:

to_dump=()
while IFS= read -r -d ''; do
  to_dump+=( "$REPLY" )
done < <(find . -maxdepth 1 -print0)
Run Code Online (Sandbox Code Playgroud)

这将创建一个名为的数组to_dump并使用该read命令从 中读取以 NULL 分隔的元素find。在< <(...)这里使用而不是管道的原因是为了避免隐式子shell,这会阻止数组被修改。

值得注意的是,您的原始find命令可能需要一个-mindepth 1, 或者它会选择.(当前目录)并且您最终会对其进行递归复制。


我注意到您将其-maxdepth 1用作 find 的参数,所以这可能更有用:

shopt -s nullglob
to_dump=( * .[!.]* ..?* )
Run Code Online (Sandbox Code Playgroud)

避免find,这仅使用 bash 内置函数,不分叉,并且在大多数情况下非常干净。

第一行shopt -s nullglob是一个 bash(-only) 命令,用于打开该nullglob选项。此选项描述于man 1 bash

如果设置,bash 允许不匹配任何文件的模式(请参阅上面的路径名扩展)扩展为空字符串,而不是它们本身。

简单来说,如果您键入*但它与文件不匹配,它将删除*. 默认行为是*无论如何都将 放在那里。

第二行将 3 个 glob 添加到数组中:

  • *: 所有不以开头的文件 .
  • .[!.]*: 所有以一.和一非.字符开头的文件。这是为了避免匹配...目录。
  • ..?*: 以..和 至少一个字符开头的所有文件。添加的原因与之前的 glob 相同,涵盖了它错过的情况。

Bash 将 glob 扩展到数组的定义中,并正确地扩展它们——不会在空格或类似的地方进行拆分。

关于使用 nullglob 的一个警告:如果你打开了 nullglob,curl google.com/search?q=test将导致 curl 抱怨你没有传递它的参数,并且ls /var/fasdfasafs*会给你一个当前目录的列表。这是默认情况下未打开的原因之一。