Я хотел бы проверить, соответствует ли имя файла определенному шаблону

Добавить к daisy ответ:

Если вы хотите, чтобы это изменение сохранилось после перезагрузки, поместите его в файл /etc/fstab, например.

.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,defaults 0 0

0
04.07.2019, 16:04
3 ответа

Если вы преобразуете расширенное регулярное выражение в шаблон подстановки, вы можете использовать case... esacв dash, чтобы проверить, соответствует ли ему значение вашей переменной, не привлекаяgrep:

case $name in
    [a-zA-Z0-9]*[._-]*)
        echo success
        ;;
    *)
        echo failure
esac

Шаблон будет соответствовать значению, которое начинается с любого из символов, соответствующих [a-zA-Z0-9], а затем также содержит точку, подчеркивание или тире (, что, как я полагаю, вы хотите проверить, даже если ваше выражение позволяет последний набор символов до , а не существует в строке ). Обратите внимание, что я переместил тире в конец выражения в квадратных скобках, так как использование диапазона между .и_(.-_)не имеет большого смысла. Я также предполагаю, что вы не хотите сопоставлять буквальные обратные косые черты. Если да, добавьте \\ко второму выражению в квадратных скобках.

Что ж, этот выглядит красиво, но он не делает того, что вам нужно, поскольку *все еще может соответствовать не -буквенно-цифровому символу, который не является ., _или -.

Давайте попробуем инвертировать смысл проверки, поэтому мы проверяем имена, которые не соответствуют:

case $name in
    *[![:alnum:]_.-]*)
        echo failure
        ;;
    *)
        echo success
esac

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

case $name in
    *[![:alnum:]_.-]*)
        echo 'failure (contains wrong characters)'
        ;;
    *)
        case $name in
            [[:alnum:]]*)
                echo success
                ;;
            *)
                echo 'failure (does not start with alnum)'
        esac
esac

При этом будет выполнено не более двух проверок: сначала проверяется, содержит ли значение символ, который нам не нужен, а затем, если нет,проверяет, начинается ли он с правильного типа символа.

4
28.01.2020, 02:14

Если [[ "$filename" =~ pattern ]]недоступен, вы можете использоватьgrep:

if printf '%s' "$filename" | grep -qz 'pattern'; then
    echo "success"
else
    echo "fail"
fi

Обратите внимание, что grepиспользует основное регулярное выражение по умолчанию. Вы можете использовать расширенное регулярное выражение(-E)или регулярное выражение, совместимое с Pearl (-P), если оно доступно с вашим grep.

0
28.01.2020, 02:14

POSIX, чтобы сопоставить строку с регулярным выражением, вы можете использовать exprилиawk:

bre_match_anchored_at_start() { expr "x$1" : "x$2" > /dev/null; }
ere_match() { awk 'BEGIN{exit(!(ARGV[1] ~ ARGV[2]))}' "$1" "$2"; }

Затем вы можете использовать:

if bre_match_anchored_at_start "$string" '[a-zA-Z0-9][a-zA-Z0-9._-]*$'; then
  echo match
fi

Или:

if ere_match "$string" '^[a-zA-Z0-9][a-zA-Z0-9._-]*$'; then
  echo match
fi

Обратите внимание, однако, что соответствие a-z, A-Zили 0-9не указано и в большинстве систем довольно случайно вне локали C/POSIX. Вместо этого вы могли бы использовать[[:alnum:]](POSIX, но не поддерживается всеми реализациями awk), который снова соответствует всем буквенно-цифровым символам (, потенциально намного больше, чем 52 английских буквы и 10 десятичных цифр, если не в C локаль ). Если вы хотите сопоставить только их, вы можете сделать:

if (export LC_ALL=C; ere_match "$string" '^[a-zA-Z0-9][a-zA-Z0-9._-]*$'); then
  echo match
fi

Вы также можете добиться того же со стандартной конструкцией оболочки здесь с отрицательным подходом:

case $string in
  ("" | [!a-zA-Z0-9]* | *[!a-zA-Z0-9._-]*) ;;
  (*) echo match;;
esac
2
28.01.2020, 02:14

Теги

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