bash解析文件名

时间:2012-05-16 11:58:20

标签: bash parsing tokenize

bash中有什么方法可以解析这个文件名:

$file = dos1-20120514104538.csv.3310686

转换为$date = 2012-05-14 10:45:38$id = 3310686等变量?

谢谢

4 个答案:

答案 0 :(得分:13)

所有这一切都可以通过参数扩展来完成。请在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: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

答案 1 :(得分:3)

提取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合并在一起。

答案 2 :(得分:3)

使用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"

答案 3 :(得分:1)

您可以先为-标记字符串,然后为.标记字符串。有关如何执行此操作的各种线程:

  1. How do I split a string on a delimiter in Bash?
  2. Bash: How to tokenize a string variable?
  3. 20120514104538转换为2012-05-14 10:45:38

    由于我们知道前4个字符是年份,接下来的2个字符是月份,依此类推,您首先需要将此令牌分解为子字符串,然后重新组合成单​​个字符串。您可以从以下答案开始:

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