Shell_find命令备忘小结

参考文章

问题来源:Kaldi librispeech example:数据预处理脚本文件:

path = kaldi/egs/librispeech/s5/local/da ta_prep.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 双重for循环
#第一层循环,按说话人
for reader_dir in $(find -L $src -mindepth 1 -maxdepth 1 -type d | sort); do
reader=$(basename $reader_dir)
if ! [ $reader -eq $reader ]; then # not integer.
echo "$0: unexpected subdirectory name $reader"
exit 1;
fi

# 从说话人信息文件中提取性别
reader_gender=$(egrep "^$reader[ ]+\|" $spk_file | awk -F'|' '{gsub(/[ ]+/, ""); print tolower($2)}')
if [ "$reader_gender" != 'm' ] && [ "$reader_gender" != 'f' ]; then
echo "Unexpected gender: '$reader_gender'"
exit 1;
fi

#第二重for循环,按章节
for chapter_dir in $(find -L $reader_dir/ -mindepth 1 -maxdepth 1 -type d | sort); do
chapter=$(basename $chapter_dir)
if ! [ "$chapter" -eq "$chapter" ]; then
echo "$0: unexpected chapter-subdirectory name $chapter"
exit 1;
fi

find -L $chapter_dir/ -iname "*.flac" | sort | xargs -I% basename % .flac | \
awk -v "dir=$chapter_dir" '{printf "%s flac -c -d -s %s/%s.flac |\n", $0, dir, $0}' >>$wav_scp|| exit 1

chapter_trans=$chapter_dir/${reader}-${chapter}.trans.txt
[ ! -f $chapter_trans ] && echo "$0: expected file $chapter_trans to exist" && exit 1
cat $chapter_trans >>$trans

# NOTE: For now we are using per-chapter utt2spk. That is each chapter is considered
# to be a different speaker. This is done for simplicity and because we want
# e.g. the CMVN to be calculated per-chapter
awk -v "reader=$reader" -v "chapter=$chapter" '{printf "%s %s-%s\n", $1, reader, chapter}' \
<$chapter_trans >>$utt2spk || exit 1

# reader -> gender map (again using per-chapter granularity)
echo "${reader}-${chapter} $reader_gender" >>$spk2gender
done
done

命令语句解析

1
(find -L $src -mindepth 1 -maxdepth 1 -type d | sort)
1
2
># 使用格式
>find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
1
2
3
4
>和符号链接相关的选项:
-P 不跟踪符号链接(默认行为)
-L 当 find 检查或打印有关文件的信息时, 所使用的信息应取自链接指向的文件的属性, 而不是链接本身
-H 和 -L 参数刚好相反, 当 find 检查或打印有关文件的信息时, 所使用的信息应取自符号链接的属性
1
2
3
4
5
6
7
8
9
10
11
12
>EXPRESSIONS(表达式):
OPTIONS(选项):
-d、-depth 在查找文件时, 首先查找当前目录中的文件, 然后再在其子目录中查找
-maxdepth n find 查找目录的最大深度
-mindepth n find 从指定的目录的第几层深度开始查找
-mount 查找文件时不跨越文件系统的 mount 点
-follow 和 ``-``L 参数类似
-regextype 指定后面所使用的正则表达式语法, 默认为 emacs
posix-awk 类 awk 的正则表达式语法
posix-basic 基本正则表达式
posix-egrep 不使用正则表达式
posix-extended 扩展正则表达式
1
2
3
4
5
6
7
8
>-type
b 块设备
c 字符设备
d 目录
p 命名管道
f 文件
l 链接文件
s socket 文件

🌟 想起顾芯怡教的一招

1
hdfs dfs -ls     - hdfs://haruna/home/byte_arnold_hl_speech_asr/user/huanglu.thu19/corpus/edu/chinglish_haitian_2kh_16k/wav_ark/k190/*.scp | wc -l
1
>🌟 wc -l  # 统计文件个数
1
>🌟 ls -l *.wav | wc -l  # 统计某个目录下 某种后缀的文件个数
1
>ls -l *.wav | grep "^-" | wc -l
1
>grep "^-"  # 过滤ls的输出信息,只保留一般文件,只保留目录是grep "^d"。

🌟 在自己电脑下,还是得 cd 到指定路径下才行,字节的 HDFS 数据库是只能那么读取列表,所以才可以那么用


1
2
3
4
$ basename /tmp/test/file.txt
file.txt
$ basename /tmp/test/file.txt .txt
file
1
2
3
4
>basename [pathname] [suffix]
>basename [string] [suffix]

>suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉。
1
2
3
4
>$ basename $PWD/1027.md 
>1027.md
>$ basename $PWD/1027.md .md
>1027

🌟awk 命令:一种处理文本文件的语言

1
2
# 从说话人信息文件中提取性别
reader_gender=$(egrep "^$reader[ ]+\|" $spk_file | awk -F'|' '{gsub(/[ ]+/, ""); print tolower($2)}')