首页 > 解决方案 > Bash:从数组的最后一个成员迭代到第一个成员

问题描述

我正在尝试查找文件夹的“根”。我正在使用以下(至少在我的脑海中)在 Bash 脚本中执行此操作:

# Get current directory (e.g. /foo/bar/my/subdir)
CURR_DIR = `cwd`
# Break down into array of folder names
DIR_ARRAY=(${CURR_DIR//\// })

# Iterate over items in DIR_ARRAY starting with "subdir"
<HELP WITH FOR LOOP SYNTAX>
  # Each loop:
  # build path to current item in DIR_ITER; e.g.
  #   iter N: DIR_ITER=/foo/bar/my/subdir
  #   iter N-1: DIR_ITER=/foo/bar/my
  #   iter N-2: DIR_ITER=/foo/bar
  #   iter 0: DIR_ITER=/foo
  # In each loop:
  # get the contents of directory using "ls -a"
  # look for .git
  # set ROOT=DIR_ITER

export ROOT

我已经在 Bash 中搜索了循环,但它都使用“for i in ARRAY”形式,这不能保证反向迭代顺序。实现我想做的事情的推荐方法是什么?

标签: bash

解决方案


关于反向索引引用的一种想法。

首先我们的数据:

$ CURR_DIR=/a/b/c/d/e/f
$ DIR_ARRAY=( ${CURR_DIR//\// } )
$ typeset -p DIR_ARRAY
declare -a DIR_ARRAY=([0]="a" [1]="b" [2]="c" [3]="d" [4]="e" [5]="f")

我们的指数列表:

$ echo "${!DIR_ARRAY[@]}"
0 1 2 3 4 5

我们在reverse 中的索引列表:

$ echo "${!DIR_ARRAY[@]}" | rev
5 4 3 2 1 0

循环遍历我们的反向索引列表:

$ for i in $(echo "${!DIR_ARRAY[@]}" | rev)
do
    echo $i
done
5
4
3
2
1
0

至于使用这种“反向”索引策略来提升目录结构:

$ LOOP_DIR="${CURR_DIR}"
$ for i in $(echo "${!DIR_ARRAY[@]}" | rev)
do
    echo "${DIR_ARRAY[${i}]}:${LOOP_DIR}"
    LOOP_DIR="${LOOP_DIR%/*}"
done
f:/a/b/c/d/e/f
e:/a/b/c/d/e
d:/a/b/c/d
c:/a/b/c
b:/a/b
a:/a

虽然我们可以完成同样的事情 a) 没有数组和 b) 使用一些基本的参数扩展,例如:

$ LOOP_DIR="${CURR_DIR}"
$ while [ "${LOOP_DIR}" != '' ]
do
    subdir="${LOOP_DIR##*/}"
    echo "${subdir}:${LOOP_DIR}"
    LOOP_DIR="${LOOP_DIR%/*}"
done
f:/a/b/c/d/e/f
e:/a/b/c/d/e
d:/a/b/c/d
c:/a/b/c
b:/a/b
a:/a

推荐阅读