bash parse filename

倾然丶 夕夏残阳落幕 提交于 2019-12-05 02:27:57

问题


Is there any way in bash to parse this filename :

$file = dos1-20120514104538.csv.3310686

into variables like $date = 2012-05-14 10:45:38 and $id = 3310686 ?

Thank you


回答1:


All of this can be done with Parameter Expansion. Please read about it in the bash manpage.

$ 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

Combine PEs to put date back together in a new format. You could also parse the date with GNU date, but that would still require rearranging the date so it can be parsed. In its current format, this is how I would approach it:

$ 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



回答2:


Using Bash's regular expression feature:

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"



回答3:


Extract id:

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

Remove prefix, and extract core date numbers:

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

format the date like this (only partially done:)

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

You can alternatively split the initial variable into an array,

echo $f
# dos1-20120514104538.csv.3310686

after exchanging - and . like this:

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

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

echo ${ar[3]}
# 3310686

The date transformation can be done via an array similarly:

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

It splits everything into groups of 2 characters:

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

and merges 2012 together in the output.




回答4:


You can tokenize the string first for - and then for .. There are various threads on SO on how to do this:

  1. How do I split a string on a delimiter in Bash?
  2. Bash: How to tokenize a string variable?

To transform 20120514104538 into 2012-05-14 10:45:38 :

Since we know that first 4 characters is year, next 2 is months and so on, you will first need to break this token into sub-strings and then recombine into a single string. You can start with the following answer:

  1. https://stackoverflow.com/a/428580/365188


来源:https://stackoverflow.com/questions/10618015/bash-parse-filename

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!