Bash脚本根据编号归档文件

时间:2014-11-05 14:05:31

标签: linux bash

我目前正在编写一个安装samba共享的脚本,将数据rsyncs到本地计算机并归档到目录结构(比如/ home / archive /)。目前,当添加新的pdf时,手动完成归档,这似乎是对时间的低效使用

文件具有以下结构

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年或任何其他年份目录中,有以下子目录2014/Blue/,/ 2014 / Red / and / 2014 / Green /`。这对应于数字Blue(0),Red(4)和Green(6)中的第3个整数。

我在这里使用案例来查找我所谓的学习类型

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文件(不是我的调用)。

例如/ home / archive / 2014 / Blue /具有以下目录: 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,而不需要为每个Red / Blue /和Green /

采用多个if语句

2 个答案:

答案 0 :(得分:3)

这是一个简化版本,需要一些工作,但你明白了(最好的解决方案,请参阅@glenn jackman的解决方案):

声明颜色的关联数组

$ 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 + 1)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

答案 1 :(得分: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