Как пройти каталоги, из которых состоит путь в BASH - PullRequest
0 голосов
/ 13 мая 2019

Я собираюсь запрограммировать анализатор файлов, работающий в древовидной структуре каталогов.Как только я нахожу конкретный конечный каталог, я хочу просмотреть все каталоги, из которых состоит путь, и выполнить в них некоторые операции.

Скажем, путь: /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

Но есть ли более элегантное решение для этого?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 14 мая 2019

Теперь я нашел другое решение, используя внутренний разделитель полей.Каталог / также считается.

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
0 голосов
/ 14 мая 2019

Пожалуйста, попробуйте следующее:

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

Все сводится к проблеме, как генерировать верхние каталоги из данный путь. Мой код выше будет работать для обоих случаев абсолютный путь и относительный путь. Чтобы принять путь, который начинается с . или .., небольшой потребуется модификация в регулярном выражении.

[EDIT]

Если вы хотите обработать заказ как 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

[EDIT]

Если вы хотите включить корневой каталог / в путь поиска, когда указан абсолютный путь, пожалуйста попробуйте:

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
0 голосов
/ 13 мая 2019

Это то, что вы пытаетесь сделать (не проверено)?

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
...