【问题标题】:Bash script to reorganize files based on part of their file name. Ubuntu用于根据文件名的一部分重新组织文件的 Bash 脚本。 Ubuntu
【发布时间】:2015-12-16 20:13:29
【问题描述】:

我正在尝试重新组织目录。之前设置了一个脚本,将 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'开头

【问题讨论】:

  • 您应该先尝试解决自己的问题,然后再在这里提问。请展示您所做的任何尝试以及失败的原因。
  • mv /var/spool/folder/2015-12-16/*20151215* /var/spool/folder/2015-12-15/.?
  • @jesse-sielaff。之前用过cut,完全忘记了。谢谢,这应该会有所帮助。

标签: bash shell


【解决方案1】:

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】:

    awk 救援

    而不是所有cuts 来提取您可以简单使用的日期

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

    例如

    $ 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
    

    【讨论】:

      【解决方案3】:

      我最终使用了反向剪辑:

      #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
      

      【讨论】:

        猜你喜欢
        • 2020-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-03
        • 2014-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多