最近都在操作日志文件,所以接触到了一些命令,好记性不如烂笔头
正则表达式
linux下经常会用到正则表达式,所以需要一点简单的正则表达式知识。
\: 忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
\<:从匹配正则表达 式的行开始。
>:到匹配正则表达式的行结束。
[ ]:单个字符,如[A]即A符合要求 。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
。:所有的单个字符。
*:有字符,长度可以为0。
vim
join
功能:“将两个文件里指定栏位同样的行连接起来”,即依照两个文件里共有的某一列,将相应的行拼接成一行。
join [options] file1 file2
注:这两个文件必须在已经在此列上是依照同样的规则进行了排序。
join选项
-a FILENUM:除了显示匹配好的行另外将指定序号(1或2)文件里部匹配的行显示出来
-e EMPTY:将须要显示可是文件里不存在的域用此选项指定的字符取代
-i :忽略大写和小写
-j FIELD :等同于 -1 FIELD -2 FIELD,-j指定一个域作为匹配字段
-o FORMAT:以指定格式输出
-t CHAR :以指定字符作为输入输出的分隔符
join 默认以空白字符做分隔符(空格和\t),能够使用 join -t $’\t’来指定使用tab做分隔符
-v FILENUM:与-a相似 但值显示文件里没匹配上的行
-1 FIELD:以file1中FIELD字段进行匹配
-2 FIELD:以file2中FIELD字段进行匹配
–help :打印命令帮助文件
sed
sed [-nefr] [动作]
选项与参数:
-n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e :直接在命令列模式上进行 sed 的动作编辑;
-f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
-r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
-i :直接修改读取的文件内容,而不是输出到终端。
动作说明: [n1,n2]function
n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』
function:
a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
g : 匹配每一行有行首到行尾的所有字符
sed ‘s///g’ 与sed ‘s///’ 其实是有很大区别的
加g :匹配每一行有行首到行尾的所有字符
不加g:匹配每一行的行首开始匹配,匹配到第一个符合的字段,就会结束,跳到下一行
http://luzhi1024.blog.51cto.com/8845546/1650729
awk
一篇讲解awk炒鸡详细的文章:http://www.cnblogs.com/emanlee/p/3327576.html
NR 与FNR的区别与使用
NR : 到目前为止记录数(Number of Record)
FNR : 当前文件中的记录号(File Number of Record)
在awk里,NR和FNR的含义相近,唯一的区别就是作用范围,NR是所有读取的行信息计数,而FNR是正在读取文件的行信息技术,FNR在文件切换时会从0重新开始计数
上例子:
a.txt
张三|000001
李四|000002
b.txt
000001|10
000001|20
000002|30
000002|15
执行语句:
awk -F '|' 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' a.txt b.txt
得到结果:
张三|000001|10
张三|000001|20
李四|000002|30
李四|000002|15
这个操作在数据库里做的比较多,就像left join。
NR==FNR,判断是否正在读第一个文件a.txt。awk会加载a.txt、b.txt两个文件,NR记录的是读取过的所有行数(到最后NR是a.txt和b.txt的总行数),而FNR读取当前文件(a.txt或b.txt)的行数,当开始读b.txt时,FNR会清零。
NR==FNR{a[ 2]= 0;next},如果是正在读取a.txt,则把当行数据 0赋值给数组a,键值是第二列数据 2,如:当行数据是“张三|000001”,则:a[‘000001’]=’张三|000001’。next嘛,就相当于java里循环的continue。
- {print a[ 1]"|" 2} ,这里读取到了b.txt。
grep
grep [options] [–color=auto] ‘keyword’ fileName
[options]:
-A: 显示匹配关键字的下n行
-B: 显示匹配关键字行的上n行
-c:只输出匹配行的计数。
-I:不区分大 小写(只适用于单字符)。
-h:查询多文件时不显示文件名。
-l:查询多文件时只输出包含匹配字符的文件名。
-n:显示匹配行及 行号。
-s:不显示不存在或无匹配文本的错误信息。
-v:显示不包含匹配文本的所有行。
-w: 只匹配整个单词,而不是字符串的一部分(如匹配‘magic’,而不是‘magical’)
–color: 显示关键字颜色
- 查看匹配关键字的下2行
grep -A 2 test.txt
- 匹配多个关键字
//或匹配
grep -E 'AA|BB' test.txt
grep -E --color 'AA|BB' test.txt /*高亮关键字*/
//与匹配
grep pattern1 files | grep pattern2 | grep pattern3
grep 'AA' test.txt | grep 'BB' |grep 'CC'
日志操作记录
分离地市码
日志文件:pCode.txt
862 甘肃省 86229 临夏回族自治州
862 甘肃省 86230 甘南藏族自治州
863 青海省 86301 西宁市
863 青海省 86321 海东地区
863 青海省 86322 海北藏族自治州
863 青海省 86323 黄南藏族自治州
863 青海省 86325 海南藏族自治州
863 青海省 86326 果洛藏族自治州
863 青海省 86327 玉树藏族自治州
863 青海省 86328 海西蒙古族藏族自治州
863 青海省 86329 格尔木
864 宁夏回族自治区 86401 银川市
864 宁夏回族自治区 86402 石嘴山市
864 宁夏回族自治区 86403 吴忠市
864 宁夏回族自治区 86404 固原市
864 宁夏回族自治区 86405 中卫市
865 新疆维吾尔自治区 86501 乌鲁木齐市
865 新疆维吾尔自治区 86502 克拉玛依市
865 新疆维吾尔自治区 86521 吐鲁番地区
865 新疆维吾尔自治区 86522 哈密地区
865 新疆维吾尔自治区 86523 昌吉回族自治州
865 新疆维吾尔自治区 86527 博尔塔拉蒙古自治州
865 新疆维吾尔自治区 86528 巴音郭楞蒙古自治州
......
现在想把省级和市级的分开成两个文件。
//读取文件 | awk,获取1、2列数据 | 排序并去重
cat pCode.txt | awk -F '\t' '{print $1"|"$2}' | sort -n -u > provinceCode.txt
cat jtCode.txt | awk -F '\t' '{print $3"|"$4}' | sort -n -u > cityCode.txt
省份txt:provinceCode.txt
862|甘肃省
863|青海省
864|宁夏回族自治区
865|新疆维吾尔自治区
911|港澳台地区
......
市级txt: cityCode.txt
86229|临夏回族自治州
86230|甘南藏族自治州
86301|西宁市
86321|海东地区
86322|海北藏族自治州
86323|黄南藏族自治州
86325|海南藏族自治州
86326|果洛藏族自治州
86327|玉树藏族自治州
86328|海西蒙古族藏族自治州
86329|格尔木
86401|银川市
86402|石嘴山市
86403|吴忠市
86404|固原市
86405|中卫市
86501|乌鲁木齐市
86502|克拉玛依市
86521|吐鲁番地区
86522|哈密地区
86523|昌吉回族自治州
86527|博尔塔拉蒙古自治州
86528|巴音郭楞蒙古自治州
......
然后我在政府行政网站上拿到全国最新的地方编码表,大概是这样的:
632823 天峻县
640000 宁夏回族自治区
640100 银川市
640101 市辖区
640104 兴庆区
640105 西夏区
640106 金凤区
640121 永宁县
640122 贺兰县
640181 灵武市
640200 石嘴山市
640201 市辖区
640202 大武口区
......
我要做的是,把政府的地市码和我刚刚处理过的对应上。
首先是整理zf地市码的格式:
//读取 | 删除行首的空格 | 删除行末的空格 | 把中间的空格替换成'|' | 去掉县级别的
cat code.txt | sed 's/^\s\+//g' | sed 's/\s*$//g' | sed 's/\s\+/|/g' | grep -v "县" > zfCode.txt
结果zfCode.txt:
120111|西青区
120112|津南区
120113|北辰区
120114|武清区
120115|宝坻区
120116|滨海新区
120117|宁河区
120118|静海区
120119|蓟州区
......
最后就是分别把proviceCode.txt、cityCode.txt 和 zfCode.对应上
awk -F '|' 'NR==FRN{a[$2]=$0;next}{print $1"|"a[$2]}' jtProvinceCode.txt zfProvince.txt
110000|811|北京市
120000|812|天津市
130000|813|河北省
140000|814|山西省
150000|815|内蒙古自治区
210000|821|辽宁省
220000|822|吉林省
230000|823|黑龙江省
310000|831|上海市
320000|832|江苏省
......
优化,加一个流程判断
awk -F '|' 'NR==FNR{a[$2]=$0;next}{if(a[$2]==""){print $1"|-1|未知"}else{print $1"|"a[$2]}}' jtProvinceCode.txt zfProvince.txt
【未完待续……】
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2856896.html
http://www.2cto.com/os/201404/296597.html