Как использовать поиск с переменной и подстановочными знаками

#bash #shell

#bash #оболочка

Вопрос:

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

     #!/bin/bash
    # Sample inputs: 
    # http://testurl.com/post/1234
    # http://testurl.com/post/5678

    folder=""
    if [[ $1 == *"post"* ]]; then
        folder=${1##*/}
        folder=${folder//[$'trn ']}
    fi
    
    if [[ $(find "$HOME" -name "*$folder*" -print -quit) ]]; then
        echo 'Hi'
    else
        echo 'Bye'
    fi

    # Sample directories:
    # /home/user/1234
    # /home/user/0001
  

Везде, где я смотрел, мне говорят, что это должно работать идеально. Однако это работает не так, как должно, и я занимался этим часами. Кто-нибудь может мне помочь?

Версия Bash: GNU bash, версия 5.0.3(1) -release (x86_64-pc-linux-gnu)

Комментарии:

1. Что вы подразумеваете под «не выполняется должным образом»? Какого поведения вы ожидаете, какое поведение вы видите?

2. что вы хотите сделать в первую очередь?

3. @choroba Я ожидаю увидеть «Привет», когда программа найдет папку, содержащую цифры в конце URL-адреса, и «Пока», когда она ее не найдет. Я вижу «Привет» независимо от входных чисел, соответствующих существующим именам каталогов

4. Попробуйте запустить его, set -xv чтобы увидеть, что было найдено.

Ответ №1:

это упрощает проверку find того, найдено ли что-то, используя стандартные grep , а не bashisms:

 if find "$HOME" -type d -name "$folder" -print -quit | grep .; then
  echo "Hi"
else
  echo "Bye"
fi
  

я также изменил два ограничения для find :

  • поиск только по каталогам: -type d
    • таким образом, вы не получаете обычные файлы
  • ищите только те пути, в которых базовое имя (последний компонент полного пути) ${folder} точно совпадает
    • таким образом, вы не получаете совпадений для /home/user/12345 или /home/user/.emacs.d/auto-save-list/.saves-12350-localhost~

по практическим соображениям (как только станет известно, что скрипт работает), я бы отказался от вывода grep , перенаправив его на /dev/null )

если все каталоги находятся непосредственно в «$ {HOME}», вы также можете добавить -maxdepth 1 в качестве первого аргумента to find (чтобы не возвращаться в подкаталоги).

таким образом, вы получаете что-то вроде:

 if find "$HOME" -maxdepth 1 -type d -name "$folder" -print -quit | grep . >/dev/null
then
  echo "Hi"
else
  echo "Bye"
fi
  

или просто используйте:

 if [ -d "${HOME}/${folder}" ]; then
  echo "Hi"
else
  echo "Bye"
fi
  

Комментарии:

1. Поиск был слишком широким и обнаружил, что кеши firefox содержат числа, поэтому программа не будет запускаться, потому что она продолжала говорить, что каталог существует. Спасибо за вывод grep, потому что я бы начал рвать на себе волосы.

2. Также спасибо за дополнительную информацию! Вдохновил меня на другие функции!