bash анализира името на файла

Има ли някакъв начин в bash да анализирате това име на файл:

$file = dos1-20120514104538.csv.3310686

в променливи като $date = 2012-05-14 10:45:38 и $id = 3310686?

Благодаря ти


person pufos    schedule 16.05.2012    source източник
comment
Не знам как да го направя .. Питам дали някой е правил това, защото не знам откъде да започна...   -  person pufos    schedule 16.05.2012
comment
Прочетохте ли страницата с ръководство за bash? Има цял раздел за разширяване на променливи, който трябва да ви даде някои идеи.   -  person larsks    schedule 16.05.2012
comment
възможен дубликат на Как анализирате име на файл в bash?   -  person Romain    schedule 16.05.2012


Отговори (4)


Всичко това може да се направи с Parameter Expansion. Моля, прочетете за това в страницата за ръководство на bash.

$ file='dos1-20120514104538.csv.3310686'
$ date="${file#*-}" # Use Parameter Expansion to strip off the part before '-'
$ date="${date%%.*}" # Use PE again to strip after the first '.'
$ id="${file##*.}" # Use PE to get the id as the part after the last '.'
$ echo "$date"
20120514104538
$ echo "$id"
3310686

Комбинирайте PE, за да съберете отново датата в нов формат. Можете също така да анализирате датата с GNU date, но това пак ще изисква пренареждане на датата, така че да може да бъде анализирана. В настоящия му формат, ето как бих подходил към него:

$ date="${date:0:4}-${date:4:2}-${date:6:2} ${date:8:2}:${date:10:2}:${date:12:2}"
$ echo "$date"
2012-05-14 10:45:38
person kojiro    schedule 16.05.2012

Използване на функцията за регулярен израз на Bash:

file='dos1-20120514104538.csv.3310686'
pattern='^[^-]+-([[:digit:]]{4})'
for i in {1..5}
do
    pattern+='([[:digit:]]{2})'
done
pattern+='\.[^.]+\.([[:digit:]]+)$'
[[ $file =~ $pattern ]]
read -r _ Y m d H M S id <<< "${BASH_REMATCH[@]}"
date="$Y-$m-$d $H:$M:$S"
echo "$date"
echo "$id"
person Dennis Williamson    schedule 17.05.2012

ID на извличане:

f='dos1-20120514104538.csv.3310686'
echo ${f/*./}
# 3310686
id=${f/*./}

Премахнете префикса и извлечете основните дати:

noprefix=${f/*-/}
echo ${noprefix/.csv*/}
# 20120514104538
ds=${noprefix/.csv*/}

форматирайте датата по този начин (направено само частично:)

echo $ds | sed -r 's/(.{4})(.{2})(.{2})/\1.\2.\3/'

Можете алтернативно да разделите първоначалната променлива в масив,

echo $f
# dos1-20120514104538.csv.3310686

след размяна - и . като този:

echo ${f//[-.]/ }
# dos1 20120514104538 csv 3310686

ar=(${f//[-.]/ })
echo ${ar[1]}
# 20120514104538

echo ${ar[3]}
# 3310686

Трансформацията на датата може да се извърши чрез масив по подобен начин:

dp=($(echo 20120514104538  | sed -r 's/(.{2})/ \1/g'))
echo ${dp[0]}${dp[1]}-${dp[2]}-${dp[3]} ${dp[4]}:${dp[5]}:${dp[6]}

Той разделя всичко на групи от 2 знака:

echo ${dp[@]}
# 20 12 05 14 10 45 38

и обединява 2012 заедно в изхода.

person user unknown    schedule 16.05.2012
comment
@VictorYarema: Моля, не поставяйте любимата си подкана пред командите. Това прави по-трудно копирането/поставянето им и те не са част от кода. - person user unknown; 05.11.2015
comment
Съгласен. Съжалявам за това. Направих го като в някои други въпроси и отговори, за да направя по-лесно разграничаването на командата и изхода. По-късно забелязах проблема, който току-що посочихте. След това открих, че някои други потребители просто пишат изходи, коментирани. Последният подход го прави още по-добър - можете да копирате команди с коментирани изходи и да ги изпълнявате безопасно. Просто нямах време да премина към този стил. - person Victor Yarema; 05.11.2015
comment
Бихте ли приели, ако добавя решетки в началото на всеки изходен ред? - person Victor Yarema; 05.11.2015
comment
@VictorYarema: Тъй като изходът не може да се интерпретира (от обвивката) в разумни случаи като нова команда, най-лошото нещо, което може да се случи, е реакция „команда не е намерена: 20120514104538“ или други подобни. И ако потребителят прочете кода и се опита да го разбере, той трябва да е очевиден. Въпреки това, аз го направих сам (поставих хеш отпред за подчертаване на синтаксиса/цветна декорация), така че бих приел такива редакции. - person user unknown; 05.11.2015
comment
Фиксирани (коментирани изходи и име на файл в кавички). Благодаря за моя преглед на редакцията, който се превърна в връщане. Благодаря, че бяхте толкова внимателни. :) - person Victor Yarema; 05.11.2015

Можете да токенизирате низа първо за - и след това за .. Има различни теми на SO за това как да направите това:

  1. Как да разделя низ на разделител в Bash?
  2. Bash: Как да токенизирам низова променлива?

За да трансформирате 20120514104538 в 2012-05-14 10:45:38:

Тъй като знаем, че първите 4 знака са година, следващите 2 са месеци и така нататък, първо ще трябва да разделите този токен на поднизове и след това да го комбинирате отново в единичен низ. Можете да започнете със следния отговор:

  1. https://stackoverflow.com/a/428580/365188
person Ozair Kafray    schedule 16.05.2012
comment
Добре, сега да направя трансформиране на 20120514104538 в 2012-05-14 10:45:38 - person pufos; 16.05.2012