将大量文件复制到日期结构化目录顺序中

将大量文件复制到日期结构化目录顺序中

我需要将大约 40.0000 个文件复制到日期结构文件夹中。
示例文件:

/var/public/voicelogging/quality_monitoring/20151209/bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

是我需要复制到的众多文件之一/home/username/logging/

文件名中有两个我需要使用的变量:

bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

20151209当然,日期
12434是创建该文件的用户的 ID。

我需要的是一个脚本/一个衬垫,可以在目录中搜索用户 ID。

然后使用用户 ID 创建一个目录/home/username/logging。创建文件夹后,它需要为它可以找到的每个日期创建一个目录。
并将每个文件放入正确的userid/date目录中。
结果目录示例

/home/username/logging/12434/20151209/bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

我已经构建了一个用于制作日期目录的单行,但我仍然需要自己制作用户 ID 目录。

find /var/public/voicelogging/quality_monitoring/ -type f -name "*12434*" | sed -r 's/^.{65}//' | cut -c1-8 | xargs -I {} mkdir {} /home/username/logging/12434

如何将正确的文件复制到正确的位置?

答案1

find与的一种方式install

find /var/public/voicelogging/quality_monitoring -name \*.WAV -exec sh -c '
bn=${0##*/}; x=${bn%%-*}; dt=${x##*_}; y=${bn%_*}; id=${y##*_} 
install -D "$0" "/home/username/logging/${id}/${dt}/${bn}"' {} \;

这使用参数扩展从文件名中提取日期:${dt}和用户 ID:,${id}然后使用install将每个文件复制到相应的userID/date目录(这是因为我很懒) - 不将install最后一行替换为:

dest=/home/username/logging/${id}/${dt}; mkdir -p "${dest}" && cp "$0" "${dest}"' {} \;

如果您喜欢循环遍历这些“日期”目录,然后循环遍历.WAV每个目录中的文件:

for d in /var/public/voicelogging/quality_monitoring/*; do
  dt=${d##*/}
  for f in $d/*.WAV; do
    bn=${f##*/}; y=${bn%_*}; id=${y##*_}
    dest=/home/username/logging/${id}/${dt}
    mkdir -p "${dest}" && cp "${f}" "${dest}"
  done
done

如果你有zsh它更容易和更短zmv(也因为zsh它更聪明,你可以嵌套变量扩展,例如${${file%_*}##*_}足以提取用户ID):

dtcp () {                                                                     
mkdir -p $3 && cp $1 $2 $3
}
autoload zmv
zmv -n -p dtcp '/var/public/voicelogging/quality_monitoring/(*)/(*).WAV' \
'/home/username/logging/${${2%_*}##*_}/$1'

s(*)创建可在第二个参数中使用的反向引用,如$1$2
此处zmvwith-p执行函数dtcp而不是mv。该函数创建目录,然后将文件复制到新创建的目录中。参数(不要误认为是上面的反向引用)是:
$1:--
表示选项结束
$2:/var/public/voicelogging/quality_monitoring/(*)/(*).WAV'
是必须复制的文件
$3:/home/username/logging/${${2%_*}##*_}/$1
是目标
注意-n代表试运行;删除它以实际运行该命令。

相关内容