Скрипт для проверки наличия и сравнения количества файлов каталогов

Я все еще новичок в unix и сценариях, и я пытаюсь написать сценарий, который может принимать входной каталог от пользователя, проверять, существует ли он, затем сравните количество файлов в данном каталоге с текущим каталогом и сообщите, в котором больше файлов. Мой код в основном работает, пока я ввожу дочерний каталог. Если я попытаюсь использовать сценарий и ввести родительский или другой дочерний элемент в другую ветку, он не сможет найти каталог, даже если указан полный путь. Я знаю, что аналогичные вопросы были заданы относительно команды test, но ни один из них (который я смог найти) не касался того, что делать, когда test не может распознать каталог, который действительно существует.

dir1=$(pwd)
read -rp "Input the path..." dir2
    if [ ! -d "$dir2" ]; then
    echo "...does not exist"
    else
    ...

... остальная часть кода работает нормально. В этом и кроются проблемы.

РЕДАКТИРОВАТЬ: Общая идея состоит в том, чтобы найти любой каталог из любого другого каталога, но этого не происходит. Например, из моего ~ / public_html как pwd, если я запускаю скрипт и ввожу ~ / schoolwork или даже полный путь, он не может распознать каталог.

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

0
28.07.2017, 22:12
2 ответа

Вы можете сделать свой сценарий оболочки следующим образом:---

#!/bin/bash
read -rp "Input the path..." dir2
dir1=$pwd
#First Check the existence of directory
if [[ -d "$dir2" ]]
    then
    #If it is a valid directory then count the number of files in each directory
    count1=$(find $dir1 -type f | wc -l)
    count2=$(find $dir2 -type f | wc -l)
    #Compare the number of files in the two directories
    if [ $count1 -gt $count2 ]
         then
         echo "Current Directory has more files"
    else if [ $count1 -eq $count2 ]
         then
         echo "Both Directories have same number of files"
    else 
         echo "Input Directory has greater number of files"
    fi
    fi
else
    #If not a valid directory
    echo "Invalid Directory"
fi
-1
28.01.2020, 05:05

Проблема, с которой вы столкнулись, связана с расширением тильды. Если вы введете ~/schoolworkв приглашении вашего сценария, тильда в начале будет просто еще одним символом и не будет расширена до пути к вашему домашнему каталогу, когда вы проверите его с помощью [ ! -d "$dir2" ]. Точно так же вы не сможете ввести $HOME/schoolwork, так как переменная $HOMEникогда не будет расширена.

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

Итак, вы хотите, чтобы ваш пользователь использовал ваш скрипт как

./script.sh path/to/some/directory

Например,

./script.sh ~/schoolwork

Здесь оболочка расширила бы путь перед вызовом вашего скрипта, и скрипт получил бы путь вроде /home/turfer/schoolworkв качестве своего первого и единственного аргумента.

Итак, как написать этот скрипт?

Вот предложение для начала:

#!/bin/bash

userdir=$1  # the directory pathname passed on the command line

if [ ! -d "$userdir" ]; then
    printf 'Your directory, %s, does not exist\n' "$userdir" >&2
    exit 1
fi

Теперь нам нужно подсчитать количество файлов как в текущем каталоге, так и в $userdir. Предположим, что мы действительно имеем в виду файлы любого типа (, включая сокеты, символические ссылки, каталоги и т. д. ).

shopt -s dotglob   # also match hidden names

herefiles=(./* )
therefiles=( "$userdir"/* )

Если вы хотите подсчитывать только обычные файлы , вы должны циклически перебирать вещи, соответствующие этим двум шаблонам, и рассматривать только те вещи, которые проходят [ -f... ]тест (, хотя это все равно будет учитываться. символические ссылки на обычные файлы ).

Теперь у нас есть все имена всего в текущем каталоге и в указанном пользователем -каталоге в двух массивах. Теперь нам просто нужно сравнить длины этих массивов и сказать, какой из них самый длинный.

if [ "${#herefiles[@]}" -gt "${#therefiles[@]}" ]; then
    printf 'There are more files here than in %s\n' "$userdir"
elif [ "${#herefiles[@]}" -lt "${#therefiles[@]}" ]; then
    printf 'There are more files in %s than in here\n' "$userdir"
else
    printf 'There are an equal number of files here as in %s\n' "$userdir"
fi

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

0
28.01.2020, 05:05

Теги

Похожие вопросы