bash Сценарии для итерации по указанным c каталогам в пути к целевому файлу и игнорирования определенных каталогов - PullRequest
1 голос
/ 06 февраля 2020

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

dirName="file-path/folder-name"

for dir in $(ls -d */); do
    dirName=${dir%/}

    pid=`cat $parentDir/$dirName/$dirName.lck`

    if [ -n "$pid" ]
    then
            printf "$dirName : RUNNING \n"

    fi

    cd ..
done

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

Запросите помощь по этому вопросу, поскольку я пытаюсь выяснить альтернативы.

Ответы [ 4 ]

1 голос
/ 06 февраля 2020

Здесь есть две очевидные проблемы; ls не только бесполезен, но и активно проблематичен c; и многократный запуск cd .. внутри l oop определенно выглядит как ошибка. Ну три; Вы не инициализировали parentDir.

Кроме того, можно легко пропустить.

parentDir="something here, surely?"
dirName="file-path/folder-name"

for dir in ./*/; do
    case $dir in
        ./foo | ./bar | *covfefe* ) continue;;
    esac

    dirName=${dir%/}

    # Fix quoting; prefer modern command substitution syntax over backticks
    pid=$(cat "$parentDir/$dirName/$dirName.lck")

    if [ -n "$pid" ]
    then
        # Format string problem -- pass directory as argument
        printf "%s: RUNNING\n" "$dirName"
    fi
done
0 голосов
/ 06 февраля 2020

Что вам на самом деле нужно, так это файлы *.lck верно? Затем попробуйте этот подход.

path=some/path

IFS=$'\n'; for file in $(find "$path" -type f -name *.lck); {
    pid=$(cat "$file")
    # i assume that it's better to check that $pid actually exists
    [[ -e $pid ]] && echo "$(dirname $file) : RUNNING"
}

Или используя grep

while IFS=: read name pid; do
    [[ -e $pid ]] && echo "$(dirname $name) : RUNNING"
done <<< $(grep -re [[:digit:]] "$path"/*.lck)
0 голосов
/ 06 февраля 2020

Вы можете использовать find для итерации всего, что вам нужно, например:

dirName="file-path/folder-name"
for D in $(find $dirName -maxdepth 1 -type d ! -path "./dir-to-exclude/*" ! -path "./other-dir-to-exclude" );do
    echo "$D"
done

Опция -path вместе с флагом отрицания (!) Пропустит то, что вам нужно пропустить

РЕДАКТИРОВАТЬ

find . -maxdepth 1 -type d ! -path "./dir-to-exclude" ! -path "./other-dir-to-exclude" -exec sh -c 'for file do echo "$file";done' sh {} + 

Я отредактировал команду после предложения триплета, чтобы избежать пробелов без экранирования или специальных символов оболочки в именах каталогов, которые могут нарушить код

0 голосов
/ 06 февраля 2020

Вам не нужно ls

for dir in */; do
  echo "$dir"
done

Если вы хотите убрать путь.

"${dir##*/}"

измените эхо на что-то другое, то, что вы хотите сделать каталоги.

...