Lecture 4 数据整理
练习
- 学习一下这篇简短的 交互式正则表达式教程.
- 统计words文件 (/usr/share/dict/words) 中包含至少三个a 且不以's 结尾的单词个数。这些单词中,出现频率前三的末尾两个字母是什么? sed的 y命令,或者 tr 程序也许可以帮你解决大小写的问题。共存在多少种词尾两字母组合?还有一个很 有挑战性的问题:哪个组合从未出现过?
cat /usr/share/dict/words | tr "[:upper:]" "[:lower:]" | grep -E "^([^a]*a){3}.*$" | grep -v "'s$" | wc -l
> cat /usr/share/dict/words 打开这个文件
> tr "[:upper:]" "[:lower:]" tr命令将所有大写都转化为小写
> grep -E "^([^a]*a){3}.*$" -E 使用正则表达式,([^a]*a){3} 匹配零个或多个非"a"字符,后跟一个"a"字符匹配3次,之后匹配任意字符
> grep -v "'s$" "'s$" 匹配以's结尾的字符,grep -v 不显示匹配字符
> wc -l 这个命令计算输出的行数,输出结果为符合要求的单词数。
cat /usr/share/dict/words | tr "[:upper:]" "[:lower:]" | grep -E "^([^a]*a){3}.*$" | grep -v "'s$" | sed -E "s/.*([a-z]{2})$/\1/" | sort | uniq -c | sort | tail -n3
sed -E "s/.*([a-z]{2})$/\1/" "s/"进入替换模式 .*匹配任意字符 ([a-z]{2})$ 结尾处捕获两字符 "\1"使用捕获的字符替换
#!/bin/bash
for i in {a..z};do
for j in {a..z};do
echo "$i$j"
done
done
./all.sh > all.txt
cat /usr/share/dict/words | tr "[:upper:]" "[:lower:]" | grep -E "^([^a]*a){3}.*$" | grep -v "'s$" | sed -E "s/.*([a-z]{2})$/\1/" | sort | uniq > occurance.txt
diff --unchanged-group-format='' <(cat occurance.txt) <(cat all.txt) | wc -l
diff --unchanged-group-format=''
将两个文件中相同的部分设置为空字符串,剩下的就是不相同的部分,之后输出行数即可
- 进行原地替换听上去很有诱惑力,例如: sed s/REGEX/SUBSTITUTION/ input.txt > input.txt。但是这并不是一个明智的做法,为什么呢?还是说只有 sed是这样的? 查看 man sed 来完成这个问题
- sed s/REGEX/SUBSTITUTION/ input.txt > input.txt 表达式中后一个 input.txt会首先被清空,而且是发生在前的。所以前面一个input.txt在还没有被 sed 处理时已经为空了。在使用正则处理文件前最好是首先备份文件。
sed -i.bak s/REGEX/SUBSTITION/ input.txt
这段命令如果数据没有备份会自动创建.bak备份文件,直接对文件进行修改