Intereting Posts
Как быстро хранить и получать доступ к часто используемым командам? Максимальное значение максимальной памяти для всех пользователей Существует ли стандартный способ для получения пути монтирования носителя (например, / media / user, / run / media / user …)? Вставить переменную в строку в случайное место? Нормально ли, что мне нужно u + w для установки расширенных атрибутов файловой системы? Сценарий Bash для копирования текста, который в настоящее время введен для подсказки Может ли «НОВОСТИ» в пакете Debian делать упаковщик / сопровождающий? apt-get не удалось найти обновления для сжатия Debian Установка icingaweb2 / icingacli под Oracle Linux 6 Как я могу перечислить файлы по типу с помощью ls? Как написать символ «!» Между двойными кавычками в bash? Как я могу показать кириллические символы mutt на OpenBSD? Как обеспечить, чтобы скрипт bash выполнялся через сеть, не будучи в каталоге / cgi-bin? Зашифрованный автомат LVM при загрузке с ключом на другом сервере Как полностью заблокировать панель GNOME?

BASH не нравится мое регулярное выражение

Я пытаюсь получить 2-значный месяц и 2-значный год файл был изменен, но это не работает ..

modified=$(stat -c %y "$line"); # modified="2018-08-22 14:39:36.400469308 -0400" if [[ $modified =~ ".{2}(\d{2})-(\d{2})" ]]; then echo ${BASH_REMATCH[0]} echo ${BASH_REMATCH[1] fi 
  • Демоверсия Bash: http://rextester.com/DJSPH52792
  • Демонстрация RegEx: https://regex101.com/r/UEOlMO/1

Что я делаю неправильно?

Во-первых, кавычки подавляют значение специальных символов в регулярном выражении ( онлайн-руководство ):

Доступен дополнительный двоичный оператор =~ , … Любая часть шаблона может быть заключена в кавычки, чтобы принудительно сопоставить указанную часть в виде строки. … Если вы хотите сопоставить символ, который является особенным для грамматики регулярного выражения, его нужно заключить в кавычки, чтобы удалить его особое значение.

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

Во-вторых, \d делает не то, что вы думаете, а просто соответствует литералу d .

Также обратите внимание, что ${BASH_REMATCH[0]} содержит всю совпадающую строку, а индексы 1 и выше содержат захваченные группы.

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

 modified=$(stat -c %y "$file") re='^([0-9]{4})-([0-9]{2})' if [[ $modified =~ $re ]]; then echo "year: ${BASH_REMATCH[1]}" echo "month: ${BASH_REMATCH[2]}" else echo "invalid timestamp" fi 

Для файла, измененного сегодня, это дает year: 2018 и month: 08 . Обратите внимание, что числа с начальным нулем будут рассматриваться восьмеричной оболочкой и, возможно, другими утилитами.

(У четырехзначных лет меньше проблем, если вам когда-либо понадобится обрабатывать даты 1900-х годов, и их легче распознать как годы, а не дни месяца.)

Для этого не нужны регулярные выражения:

 $ touch -t 197001010000 myfile $ ls -l myfile -rw-rw-r-- 1 jackman jackman 0 Jan 1 1970 myfile $ IFS='-' read -r year month _rest < <(stat -c %y myfile) $ echo "$year:${year#??}"$month" 1970:70:01 

В качестве альтернативы с GNU date вы можете сделать:

 eval "$(date -r "$file" +'year=%Y month=%-m day=%-d')" 

Чтобы компонент года, месяца и дня изменения времени сохранялся в $year , $month и $day соответственно (в виде десятичных целых чисел, удалите - s в %-m и %-d если вы заботитесь о ведущих нулях; см. Также %y для двузначных лет).

(обратите внимание, что в отличие от GNU stat , для файлов типа symlink время модификации целевой символической ссылки рассматривается, а не время самой символической ссылки. При использовании GNU stat вы должны использовать stat -L ).