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