Bash:如何选择数组中的元素

时间:2017-12-13 20:40:56

标签: arrays bash

我有一个包含子目录和文件的数组:

~$ array=(elem1/a elem1/b elem2/a elem2/b)

我需要在子目录 elem1 中选择所有文件(及其子目录)。

我已尝试使用 for 循环和案例

for element in "${array[@]}"; do
  case $element in
    elem1*)
    # action I need to perform on this element
      echo "This is $element"
    ;;
  esac
done

我希望使用一些glob来获取我需要的元素列表,方法与此类似(从数组元素中减去子字符串):

~$ echo ${array[@]%/a}
elem1 elem1/b elem2 elem2/b

我主要担心的是,我不会硬编码我要搜索的字符串,因为我不知道它的内容 - 在我的最终版本中我得到了它们来自另一个阵列。

3 个答案:

答案 0 :(得分:2)

我的答案会在不同的行中打印数组的每个元素,然后过滤您感兴趣的元素(grep)并将它们放入新数组

newarray=( $(printf "%s\n" "${array[@]}" | grep ^elem/) )

唯一的问题是,如果数组(subdirs和file namews)的元素可能包含 EOL 或空白字符。

<强>加成

如果您的元素包含 EOL 或空白字符,则应使用 NUL \000)字符和grep -zZ来处理它;但是你需要更多的代码才能将那些NUL-char字符串变成bash可以使用的东西 - 当bash找到NUL字符时bash停止读取。

在这个例子中,我使用awk来处理NUL字符没有问题,并且不必使用grep

 eval newarray=( $(printf "%s\000" "${A[@]}" |
                   awk 'BEGIN { FS="\000" }

                        /^elem\// {
                                    gsub("\042","\\\042")
                                    printf("[" NR-1 "]=\042%s\042 ",$0)
                                  }'
                   )
                )

答案 1 :(得分:1)

这是另一种选择

$ for e in "${array[@]}"; 
  do case "${e%%/*}" in
       elem1) echo "$e is in elem1" ;;
     esac
  done

elem1/a is in elem1
elem1/b is in elem1

答案 2 :(得分:1)

您可以使用变量查询(下面为prefix)过滤数组,并将结果存储在新数组(result)中:

#!/bin/bash
array=(elem1/a elem1/b elem2/a elem2/b)
prefix=elem1
result=()
for element in "${array[@]}"; do
    [[ $element == $prefix/* ]] && result+=("$element")
done

结果是:

$ declare -p result
declare -a result='([0]="elem1/a" [1]="elem1/b")'