2014-11-05 59 views
2
存档文件

我目前正在编写一个脚本,它装载一个samba共享,rsyncs数据到本地机器并归档到一个目录结构(比如/ home/archive /)中。目前,在加入新的PDF文件,归档手工做这似乎是低效利用的时间Bash脚本根据

具有以下结构

ABC140003.pdf 
ABC140124.pdf 
. 
. 
ABC144201.pdf 
. 
ABC146012.pdf 

/home/archive/有几个目录2010/2011/2012,2013等

的文件

基本上,我需要分解数字以找到复制文件的正确子目录。首先,我提取数

study_number=`echo $file | sed 's/[^0-9]//g'` 

那么一年

year=20`echo $study_number | cut -c 1-2` 

上述所有PDF文件都属于2014年的子目录中地2014年OR任何一年目录有以下子目录2014/Blue/,/ 2014/Red/and/2014/Green /`。这对应于数字Blue(0),Red(4)和Green(6)中的第三个整数。

我在这里使用的情况下找到我所说的学习型

type_int=`echo $study_number | cut -c 3` 
     case "$type_int" in 
     0) 
      type_string="Blue" 
      ;; 
     4) type_string="Red" 
      ;; 
     6) type_string="Green" 
      ;; 
     *) echo "$date: $file has unknown study type. Do not know where to place it" >> $logfile 
      continue 
      ;; 
     esac 

我现在知道了以下文件走在下列目录

ABC140003.pdf -> /home/archive/2014/Blue/ 
ABC140124.pdf -> /home/archive/2014/Blue/ 
. 
. 
ABC144201.pdf -> /home/archive/2014/Red/ 
. 
ABC146012.pdf -> /home/archive/2014/Green/ 

我会很高兴,如果这是目录结构的结尾。但是,还有一层子目录已经引入,因此没有超过100个pdf文件的目录(不是我的电话)。

例如/家庭/存档/ 2014 /蓝/有以下目录: 140001-0100/ 140101-0200/ 140201-0300/ 140301-0400/ 140401-0500/ 140501-0600/

我现在需要想出一些逻辑使得下列文件到以下目录

ABC140003.pdf -> /home/archive/2014/Blue/140001-0100 
ABC140124.pdf -> /home/archive/2014/Blue/140100-0124 
. 
. 
ABC144201.pdf -> /home/archive/2014/Red/144200-4300 
. 
ABC146012.pdf -> /home/archive/2014/Green/146000-6100 

我难倒就如何在逻辑上确定研究ABC146012应该在146000-6100在一个优雅的方式,而不诉诸多个if语句每个红/蓝/绿色的/

回答

3

这里是一个简化版本,需要一些工作,但你的想法(一个不错的最终解决方案,请参阅@glenn杰克曼的解决方案):

关联数组声明的颜色

$ declare -A colors 
$ colors[0]=Blue 
$ colors[4]=Red 
$ colors[6]=Green 

然后将解压所需的信息

$ study_number=$(sed 's/[^0-9]//g' <<< ABC140124.pdf); 
$ year=${study_number:0:2}; 
$ type=${study_number:2:1}; 
$ color=${colors[$type]}; 
$ from="${study_number:0:$((${#study_number}-2))}01" 
$ to="$((${study_number:0:$((${#study_number}-2))}+1))00" 

,并给出:

$ echo /home/archive/$year/$color/$from-$to 
/home/archive/14/Blue/140101-140200 

(我以为你想你的时间间隔被一致编号“x01-(X + 11)00”)

您可以创建一个函数来简化流程

build_dir() { 
    study_number=$(sed 's/[^0-9]//g' <<< $1); 
    year=${study_number:0:2}; 
    type=${study_number:2:1}; 
    color=${colors[$type]}; 
    from="${study_number:0:$((${#study_number}-2))}01" 
    to="$((${study_number:0:$((${#study_number}-2))}+1))00" 

    echo "/home/archive/$year/$color/$from-$to" 
} 

它需要多一点的防守编程相关的代码行,但它可以像这样使用:

$ build_dir ABC146012.pdf 
/home/archive/14/Green/146001-146100 
+0

梦幻般的,非常感谢。我对bash相当陌生,并从这个答案中学到了很多东西。我们在我们的部门中使用csh(不再) – moadeep 2014-11-05 14:36:25

2
colors=([0]=Blue [4]=Red [6]=Green) 

get_destination() { 
    if [[ $1 =~ ([0-9][0-9])([0-9])([0-9]) ]]; then 
     printf "/home/archive/20%s/%s/%s%s%d01-%s%d00" \ 
      ${BASH_REMATCH[1]} \ 
      ${colors[${BASH_REMATCH[2]}]} \ 
      ${BASH_REMATCH[1]} \ 
      ${BASH_REMATCH[2]} \ 
      ${BASH_REMATCH[3]} \ 
      ${BASH_REMATCH[2]} \ 
      $((1 + ${BASH_REMATCH[3]})) 
    fi 
} 

for file in ABC140003.pdf ABC140124.pdf ABC144201.pdf ABC146012.pdf; do 
    echo "$file -> $(get_destination $file)" 
done 
ABC140003.pdf -> /home/archive/2014/Blue/140001-0100 
ABC140124.pdf -> /home/archive/2014/Blue/140101-0200 
ABC144201.pdf -> /home/archive/2014/Red/144201-4300 
ABC146012.pdf -> /home/archive/2014/Green/146001-6100