0

我即将编写一个在目录树结构中运行的文件解析器。一旦我找到一个特定的叶目录,我想遍历路径所包含的所有目录并在其中执行一些操作。

假设路径是:/d1/d2/d3. 现在我想检查一个文件x是否存在于/d1,/d1/d2/d1/d2/d3分别以该顺序。

当然,可以做这样的事情:

fields=`find $base_dir -name "leaf_directory" | grep  -o "/" | wc -l`

[[ $fields > 0 ]] || exit 1

for (( i=1; i <= $fields + 1; i++ )) do
    current_dir="`find $base_dir -name "leaf_directory" | cut -d "/" -f $i`"
    source_path="$source_path$current_dir/"

    if [ -f $source_path$file ]; then
        # do sth.
    fi  
done

但是有没有更优雅的解决方案呢?

谢谢你。

4

3 回答 3

0

这是你想要做的(未经测试)吗?

fullPath='first/second/third'
mapfile -t -d '/' dirs <<<"${fullPath}/"
numDirs=$(( ${#dirs[@]} - 1 ))
path=''
file='x'
for (( dirNr=1; dirNr<=numDirs; dirNr++ )); do
    path="${path}${dirs[$dirNr]}/"
    if [[ -f "${path}${file}" ]]; then
        printf 'Found "%s"\n' "${path}${file}"
    fi
done
于 2019-05-13T17:14:28.930 回答
0

现在我找到了另一个使用内部字段分隔符的解决方案。/目录也被考虑。

path="/d1/d2/d3"
file=x

IFS='/'
unset current_path
for current_dir in $path; do
    current_path="${current_path}${current_dir}/"
    if [ -f "${current_path}${file}" ]; then
        printf '%s\n' "$current_path"
    fi  
done
unset IFS
于 2019-05-13T21:32:11.037 回答
0

请尝试以下方法:

path="aa/bb/cc"
file="x"

while true; do
    if [[ -f "$path/$file" ]]; then
        echo "Found: $path/$file"
    fi
    if [[ $path =~ ^/?[^/]+$ ]]; then
        break
    fi
    path="${path%/*}"
done

归结为如何从给定路径生成上层目录的问题。我上面的代码适用于绝对路径和相对路径的两种情况。为了接受以.or开头的路径,..需要对正则表达式进行小修改。

[编辑]

如果您想按aa, aa/bb, .. 的顺序进行处理,请尝试以下操作:

path="aa/bb/cc"
file="x"

while true; do
    array+=("$path")
    if [[ $path =~ ^/?[^/]+$ ]]; then
        break
    fi
    path="${path%/*}"
done
for (( i=${#array[@]}-1; i>=0; i-- )); do
    p="${array[$i]}"
    if [[ -f "$p/$file" ]]; then
        echo "Found: $p/$file"
    fi
done

[编辑]

如果您想/在指定绝对路径时将根目录包含在搜索路径中,请尝试:

path="/aa/bb/cc"
file="x"

while true; do
    array+=("$path")
    if [[ $path =~ ^(/|[^/]+)$ ]]; then
        break
    elif [[ $path =~ ^/[^/]+$ ]]; then
        path="/"
    else
        path="${path%/*}"
    fi
done
for (( i=${#array[@]}-1; i>=0; i-- )); do
    p="${array[$i]}"
    if [[ -f "$p/$file" ]]; then
        echo "Found: $p/$file"
    fi
done
于 2019-05-14T00:25:55.763 回答