标题这个脚本解析
1 #!/bin/bash
2
3 # Copyright 2014 Johns Hopkins University (author: Daniel Povey)
4 # Copyright 2016 Tsinghua University (author: Dong Wang)
5 # Apache 2.0
6
7 # Adapted from librispeech recipe local/download_and_untar.sh
8
9 remove_archive=false
10
11 if [ "$1" == --remove-archive ]; then
12 remove_archive=true
13 shift
14 fi
15
16 if [ $# -ne 3 ]; then
17 echo "Usage: $0 [--remove-archive] "
18 echo "e.g.: $0 /nfs/public/materials/data/thchs30-openslr www.openslr.org/resources/18 data_thchs30"
19 echo "With --remove-archive it will remove the archive after successfully un-tarring it."
20 echo " can be one of: data_thchs30, test-noise, resource"
21 fi
remove_archive用来控制是否删除压缩文件,默认不删除,如果传递–remove-archive, 解压完成之后会把下载压缩包删除,这个参数在脚本最后3行用到。16行脚本用来判断除–remove-archive参数外传递进来的参数个数是否是3,如果不是,则打印使用介绍。这里打印完没有退出当前shell, 其实应该在后面添加一个exit 1,退出当前执行, 因为
第二部分:参数赋值
23 data=$1
24 url=$2
25 part=$3
26
27 if [ ! -d "$data" ]; then
28 echo "$0: no such directory $data"
29 exit 1;
30 fi
数据目录是第一个参数,下载文件第二个参数,文件名是第三个参数
数据目录和url参数值最后一个位置都不能添加/, 比如/data不能写成/data/, 应为后面脚本会把url和part拼成完整的链接url/part.tgz
第四部分:检测目录是否存在,不存在退出。所以数据目录需要事先创建好
27 if [ ! -d "$data" ]; then
28 echo "$0: no such directory $data"
29 exit 1;
30 fi
第五部分:判断传进来下载的文件名称是否正确
32 part_ok=false
33 #list="data_thchs30 test-noise resource"
34 list="cn-celeb"
35 for x in $list; do
36 if [ "$part" == $x ]; then part_ok=true; fi
37 done
38 if ! $part_ok; then
39 echo "$0: expected to be one of $list, but got '$part'"
40 exit 1;
41 fi
list是需要下载文件名集合, part是文件名,35-37行用于检测传进来参数是否在下载集合里,38行判断检测结果,不在下载集合里退出
第六部分:判断url是否存在
43 if [ -z "$url" ]; then
44 echo "$0: empty URL base."
45 exit 1;
46 fi
第七部分:判断要下载的文件是否存在
48 if [ -f $data/$part/.complete ]; then
49 echo "$0: data part $part was already successfully extracted, nothing to do."
50 exit 0;
51 fi
首次文件下载解压完成后会创建一个.complete空文件,如果有这个文件,正常退出不用重复下载数据。
第八部分:如果要下载文件存在,判断是否是完整文件
54 sizes="6453425169 1971460210 24813708"
55
56 if [ -f $data/$part.tgz ]; then
57 size=$(/bin/ls -l $data/$part.tgz | awk '{print $5}')
58 size_ok=false
59 for s in $sizes; do if [ $s == $size ]; then size_ok=true; fi; done
60 if ! $size_ok; then
61 echo "$0: removing existing file $data/$part.tgz because its size in bytes $size"
62 echo "does not equal the size of one of the archives."
63 rm $data/$part.tgz
64 else
65 echo "$data/$part.tgz exists and appears to be complete."
66 fi
67 fi
54行是事先设置的文件大小,57行就是获取当前文件大小,等同下面这行代码
(base) root@ai-PowerEdge-R740:/opt/asr/kaldi/egs/lesson/v1# ls -l /data/cn-celeb1/cn-celeb.tgz
-rw-r--r-- 1 root root 31844634248 11月 7 2019 /data/cn-celeb1/cn-celeb.tgz
(base) root@ai-PowerEdge-R740:/opt/asr/kaldi/egs/lesson/v1# ls -l /data/cn-celeb1/cn-celeb.tgz | awk '{print $5}'
31844634248
59行用户判断文件是否完整,60行删除不完整文件,65行如果完整,打印文件已经存在,如果文件已经存在,后面的代码都别执行,当前脚本正常退出,原脚本没有加exit 0,可以根据实际需要添加退出脚本。
第九部分:如果数据不存在,则下载数据
69 if [ ! -f $data/$part.tgz ]; then
70 if ! which wget >/dev/null; then
71 echo "$0: wget is not installed."
72 exit 1;
73 fi
74 full_url=$url/$part.tgz
75 echo "$0: downloading data from $full_url. This may take some time, please be patient."
76
77 cd $data
78 pwd
79 echo " wget --no-check-certificate $full_url"
80 if ! wget --no-check-certificate $full_url; then
81 echo "$0: error executing wget $full_url"
82 exit 1;
83 fi
84 fi
74行拼接完整下载链接,所以url传进来时候最后不要带/, 文件名也不要带tgz, 否则这里拼接会有问题。
80行下载数据集, 第八部分65行并没有加退出shell exit 0, 但是这部分通过69行判断文件是否存在才下载,如果存在,不会执行下载。所以那里不退出也可以。
第十部分:解压文件
86 cd $data
87
88 if ! tar -xvzf $part.tgz; then
89 echo "$0: error un-tarring archive $data/$part.tgz"
90 exit 1;
91 fi
92
93 touch $data/$part/.complete
88行解压,93行创建空文件,主要用来和第7部分对应。后续如果一但看到这个文件,证明是完整文件夹,不用做上述重复性操作了。感觉这个设计太棒了-_-
第十一部分:删除压缩文件
97 if $remove_archive; then
98 echo "$0: removing $data/$part.tgz file since --remove-archive option was supplied."
99 rm $data/$part.tgz
100 fi
remove_archive是删除标志,这个是通过第一部分运行这个脚本时候传进来的参数–remove-archive控制的,如果不传这个参数,最后不会删除压缩包,如果传了,会在这段脚本删除下载的压缩文件。
总结:实际情况中如果修改download_and_untar.sh为自己所用呢,其实只需要改动list, 将原来文件名替换成自己要下载的文件名即可。使用直接按照下面格式使用。
ownload_and_untar.sh [--remove-archive] <data-base> <url-base> <corpus-part>