Извлечь подстроку даты из имени файла - PullRequest
2 голосов
/ 17 октября 2019

Я пытаюсь извлечь дату из пути к строке / файлу в bash. Вот то, на что я надеюсь работать, но это не так:

#!/bin/bash

f=/mnt/media/CameraUploads/CMGPH_20190626_200707386.gif

if [[ $f =~ (19|20)\d\d(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01]) ]]; then
    strresult=${BASH_REMATCH[1]}
    echo $strresult
else
    echo "unable to parse string $f"
fi

Я ожидаю $ strresult = 20190626

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Регулярное выражение Bash не поддерживает выражение \d, которое не соответствует стандарту POSIX.
Вместо этого вам нужно использовать [0-9] или [[:digit:]].

Пожалуйста, измените строки регулярного выражения следующим образом:

if [[ $f =~ (19|20)[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01]) ]]; then
    strresult=${BASH_REMATCH[0]}

Тогда вы получите:

20190626

Обратите внимание, что ${BASH_REMATCH[0]} содержит подстроку, которая соответствует всему регулярному выражению, в то время как ${BASH_REMATCH[1]} содержит часть, которая соответствует 1-му заключенному в скобки подвыражению.

Надеюсь, это поможет.

1 голос
/ 17 октября 2019

Самый простой способ - просто использовать расширение параметра с удалением подстроки , чтобы изолировать дату, а затем перейти к date -d для преобразования в дату в любом формате, который вам нравится, например,

* 1005. *

Пример использования / Вывод

$ f=/mnt/media/CameraUploads/CMGPH_20190626_200707386.gif
> t="${f%_*}"     ## trim from right to 1st '_'
> t="${t##*_}"    ## trim from left to final '_' isolating date
> date -d "$t"    ## call date format as needed
Wed Jun 26 00:00:00 CDT 2019

Вы можете сделать то же самое с частью time имени файла, если вы хотите включить это.

Чтобы выделить полную строку даты / времени, вы можете сделать:

f=/mnt/media/CameraUploads/CMGPH_20190626_200707386.gif
t="${f%.*}"     ## trim from right to 1st '.'
t="${t##*_}"    ## trim from left to final '_' isolating time
t="${t:0:2}:${t:2:2}:${t:4:2}.${t:6:3}"     ## format time with : between 
d="${f%_*}"     ## trim from right to 1st '_'
d="${d##*_}"    ## trim from left to final '_' isolating date
d="${d:0:4}-${d:4:2}-${d:6:2}"              ## format date with - between
date -d "$d $t" ## call date format as needed

Конечная строка "$d $t", переданная в date:

2019-06-26 20:07:07.386

Пример вывода

Wed Jun 26 20:07:07 CDT 2019

Правка - Дата / Время в любом месте в имени файла

Если, согласно вашему редактированию, date_time может появиться где угодно вимя файла, и если time может включать или не включать миллисекунды, эффективный способ обработки извлечения даты / времени состоит в использовании sed для выделения строки yyyymmdd_hhmmssSSSS и последующем использовании подстановки процесса передать изолированную строку в цикл while для обработки, как указано выше. (единственное изменение заключается в том, что вы проверяете, существуют ли миллисекунды перед добавлением .SSSS миллисекунд к временной строке - ограничено 4 цифрами в приведенном ниже примере - добавляйте по необходимости)

#!/bin/bash

while read line || [ -n "$line" ]; do
    d="${line%_*}"
    d="${d##*_}"    ## trim from left to final '_' isolating date
    d="${d:0:4}-${d:4:2}-${d:6:2}"          ## format date with - between
    t="${line#*_}"
    t="${t##*_}"    ## trim from left to final '_' isolating time
    t="${t:0:2}:${t:2:2}:${t:4:2}"          ## format time with : between
    [ -n "${t:6:4}" ] && t="$t.${t:6:4}"    ## append miliseconds if present
    printf "%s\n\n" "$(date -d "$d $t")"
done < <(sed 's/^[^0-9]*\([0-9][0-9_]*\).*$/\1/' "$1")

Пример входных имен файлов

$ cat file
20181214_195948-ANIMATION.gif
20191012_223451.jpg
IMG_20181122_182138511.jpg
VID_20160909_163547.3gp

Пример использования / Вывод

$ bash extract.sh file
Fri Dec 14 19:59:48 CST 2018

Sat Oct 12 22:34:51 CDT 2019

Thu Nov 22 18:21:38 CST 2018

Fri Sep  9 16:35:47 CDT 2016

Это должно охватывать имена файлов, публикуемые в комментарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...