Bash脚本根据文件名的一部分重新组织文件。 Ubuntu的

时间:2015-12-16 20:13:30

标签: bash shell

我正在尝试重新组织目录。之前设置的脚本经过并将WAV转换为MP3,然后将它们移动到日期文件夹中。问题是这个脚本并不关心文件的创建日期和脚本运行的那一天。脚本运行的日期是文件夹文件移入的日期。这部分问题我可以修复。我正在努力解决的问题是重组过去的文件。

幸运的是,文件的日期是在文件名中创建的。

如何剖析文件名以提取日期?例如:我在2015-12-16文件夹中有一些文件需要在2015-12-15。

示例文件名:

位置不佳 - / var / spool / folder / 2015-12-16 / qt1- 20151215 -123456-server-1234567890.12345.wav.mp3

我可以获取需要重新组织的所有文件的数组。他们的目标文件夹将是一个日期文件夹,格式为:

所需 - / var / spool / folder / 2015-12-15 / qt1- 20151215 -123456-server-1234567890.12345.wav.mp3

数字,命名等与文件上的内容相匹配。所有文件均以' qt1-YYYYMMDD'

开头

3 个答案:

答案 0 :(得分:0)

我最后使用了反向切割:

#Reorganize all newly created mp3s
printf "Reorganize all mp3s created in the last 60 minutes \n"
for f in $(find /var/spool/folder -name '*.mp3' -type f -cmin -60)
    do
            #Recorded date is stored in file name.
            YEAR=$( printf "$f" | rev | cut -d'-' -f4 | cut -c5-8 | rev)
            MONTH=$( printf "$f" | rev | cut -d'-' -f4 | cut -c3-4 | rev)
            DAY=$( printf  "$f" | rev | cut -d'-' -f4 | cut -c1-2 | rev)

            DATE="$YEAR-$MONTH-$DAY"

            #Check if dated folder exists. If not, create it.
            if [ ! -d "/var/spool/folder/$DATE" ]; then
                    printf "Creating directory /var/spool/folder/$DATE \n"
                    mkdir /var/spool/folder/$DATE
            fi

            if [ $( printf "$f" | rev | cut -d'/' -f3 | rev) != "folder" ];   then
                    #Move file to the appropriate folder.
                    printf "Moving $f to /var/spool/folder/$DATE \n"
                    mv $f /var/spool/folder/$DATE
            fi

done

答案 1 :(得分:0)

TXR language中的解决方案如下所示:

@(next :list @(glob "/var/spool/folder/*/*.mp3"))
@(repeat)
@  (all)
@*origdir/@basename
@  (and)
/var/spool/folder/@nil-@nil-@nil/qt1-@{year 4}@{month 2}@{day 2}-@nil.wav.mp3
@  (end)
@  (do
     (bind dir `/var/spool/folder/@year-@month-@day`)
     (unless (equal origdir dir)
       (ensure-dir dir)
       (rename-path `@origdir/@basename` `@dir/@basename`)))
@(end)

基本上我们使用glob函数通过对文件系统进行通配来生成路径列表。然后我们将此列表文本删除,就像它是一个文件一样,使用模式来匹配具有我们感兴趣的结构的路径,同时将它们分解为origdirbasename。当我们得到匹配时,我们根据提取的日期形成目标目录并确保它存在,然后将文件移动到那里。

跳过与模式不匹配的文件。如果我们期望glob找到的所有内容与模式匹配,我们可以强制执行不跳过这样的内容:

@(repeat :gap 0)

现在,行的流必须与重复的主体匹配,没有任何间隙(没有跳过行来搜索匹配)。该脚本仍将针对任何匹配路径执行移动,但在遇到第一个不匹配路径时失败。

我会首先尝试使用此rename-path更改为此,以便进行“干运行”:

(pprint `rename @origdir/@basename -> @dir/@basename`)

我没有您的数据。

答案 2 :(得分:0)

awk救援

代替所有cut来提取日期,您只需使用

即可
awk -F/ '{split($NF,a,"-"); print a[2]}'

e.g。

$ echo "/var/spool/folder/2015-12-16/qt1-20151215-123456-server-1234567890.12345.wav.mp3" 
    | awk -F/ '{split($NF,a,"-"); print a[2]}'                

20151215

您可以使用

轻松添加格式
var=$(awk ...); echo ${var:0:4}-${var:4:2}-${var:6}

sed

... | sed -r 's/(....)(..)(..)/\1-\2-\3/'

或将脚本更改为

$ echo ... | awk -F/ -v OFS="-" '{split($NF,a,"-"); 
      print substr(a[2],1,4),substr(a[2],5,2),substr(a[2],7)}'

2015-12-15