总结一下最近碰到的一些linux问题
awk命令
AWK是文本处理命令,非常适合处理格式非常规整的文本。
比如,文本内容如下:
kw car 奔驰
kw car 宝马
kw sport 足球
kw sport 篮球
#(1)现在想把种类是car的名词提取出来.(词之间以tab键隔开)
$ awk -F '\t' '{if($2=="car") print $0}' file.name
#(2)挑出第三列为“宝马”的行内容
$ awk -F '\t' '{if($3=="宝马") print $0}' file.name
#(3)列数量不确定,但是还要输出最后一行,怎么办
$ awk -F '\t' '{print $NF}' file.name
#(4)输出第二列的字符长度
$ awk -F '\t' '{print length($2)}' file.name
$ awk -F '\t' '{print length($2)"\t"$2}' file.name
#(5)筛选条件可以更复杂,多个条件
## and逻辑
$ awk -F '\t' '{if($1=="kw" && $2=="car") print $0}' file.name
## or逻辑
$ awk -F '\t' '{if($3=="足球" || $2=="car") print $0}' file.name
# NOTICE:awk是按行读取并进行处理的。
# -F '\t' 表示每行的列之间以tab键作为分隔符,如果不设定,表示以tab和空格键为分隔符。
# 指定多个分隔符 -F '[;:\t ]'空格也可以放到里面
egrep命令
egrep是文本匹配命令,非常适合字符匹配查询。(egrep 是grep的高级版)
kw entity 欢乐颂
kw entity 欢乐颂 关关(注意欢乐颂与关关之间是空格,其他词之间是tab)
kw entity 爱因斯坦
#(1)现在从中挑出带有“欢乐颂”的行内容
$ egrep "欢乐颂" file.name
#(2)在文本量很大时,可以用egrep选出数据时,尽量不要用awk去取数据,或者用egrep取数据,再用|awk来处理数据,这样会快很多。具体数据多大呢,上百万行的数据会有明显区别。
# 比如,需要筛选 欢乐颂,且某列符合某一条件的内容
$ awk -F '\t' '{if($3=="欢乐颂" && $2=="entity") print $0}' file.name
$ awk -F '\t' '{if($3~"欢乐颂") print $0} file.name | awk -F '\t' '{if($3=="欢乐颂" && $2=="entity") print $0}'
$ egrep "欢乐颂" file.name | awk -F '\t' '{if($3=="欢乐颂" && $2=="entity") print $0}'
# 上述,最后一个要快很多哈~
#(3)搜索\$这样的符号
egrep '\\' file.name 或者 egrep "\\\\" file.name 搜索\
egrep '\$' file.name 或者 egrep "\\\$" file.name 搜索$
# 单引号和双引号对中文没有影响,主要在特殊字符上,建议用单引号。
cat命令
cat 在平时使用的比较少,用的时候再说吧。也是按行读入处理。
# 也可以用其他命令用管道“|”连接起来。
# 将某文本按行读入到Python处理程序中。
$ cat file.name | python python.py
# 数据的拼接,交集,并集
$ cat path/of/file-1 path/of/file-2 > file3 两份文件合并,append
$ cat path/of/file-1 path/of/file-2 | sort | uniq > file3 两份文件合并,排序并去重。
# Notice:先排序,再去重,因为去重机制是将相邻的重复值保留一份。
$ cat path/of/* > file 目录下的所有文件直接合并,append
# 思考,可否cat path/of/* | sort | uniq > file呢?
# 答案是否定的,两份文件可以,多份是无法达到排序去重的,因为排序是两个之间进行的。多个文件无法处理,可以先直接合并,再对合并后的文件进行排序和去重。sort -u file.name
$ cat path/of/file-1 path/of/file-2 | sort | uniq -d > jiaoji 两份文件的交集
$ cat path/of/file-1 path/of/file-2 | sort | uniq -u > except-jiaoji两份文件去掉交集之后,剩余的内容合并到一起。
交叉使用
Linux下有“管道”这个好东东,可以让我对数据处理更为方便。
kw car 奔驰
kw car 宝马
kw sport 足球
kw sport 篮球
kw video 欢乐颂
kw entity 欢乐颂 关关
kw entity 爱因斯坦
# 现在从中选出种类为“entity”且名称为“欢乐颂”的行内容。
$ egrep "欢乐颂" file.name | awk -F '\t' '{if($2=="entity") print $0}'
# Notice:awk 可以用“|”连接起来,最好两个,不要连太多。
$ awk -F '\t' '{if($1=="kw") print $0}' file.name | awk -F '\t' '{if($2=="sport") print $0}'
shell
#(1)shell 获取外部变量
data=$i, i=[1, 9]
# 可以获取1~9个参数(这些就足够了)
#(2)shell脚本里awk使用变量作为语句一部分
var=13
awk -F '\t' '{if($3>='"$var"') print $0}' file.name
# 这里不能直接($3>="$var")。采用单引号嵌套进去。
#(3)*在shell脚本里出现作为模糊时
# 比如某shell命令需要取某个路径下的所有内容
command ... /data/dir/"pre_"${date}"*" 这种是无法取所有的
command ... /data/dir/"pre_"${date}* 这样才可以取所有
#(4)shell里面时间、时间戳获取
# 获取今天、昨天、明天的时间。
today=$(date +%Y%m%d)
echo $today
yesterday=$(date +%Y%m%d -d "-1 days")
echo $yesterday
tommorow=$(date +%Y%m%d -d "1 days")
echo $tommorow
# 可以用+%Y%m%d%H -d "-1 hours"获取前一个小时的时间
# 获取当天零点零刻的时间戳
today=$(date +%Y-%m-%d)
STD=$(date -d $today +%s)
#(5)shell脚本的执行
# shell脚本的执行时,都要跳转到所在文件的路径下,否则会出错。
# (6) shell内部循环指定的文件列表 #
filepre=./your/dir/
for i in $(ls ${filepre} | grep 'mathch condition')
do
file=${filepre}${i}
echo $file
# do sth yourself #
done
# (7)
python
#(1)字典循环
for key, value in dict.items()
print key + "\t" +str(value)
#(2)字典排序
## 按照key排序(升序):
a = sorted(dict.iteritems(), key=lambda d:d[0], reverse=False)
## 按照value排序(降序):
a = sorted(dict.iteritems(), key=lambda d:d[1], reverse=True)
#(3)sys.stdin.readline()的使用,可以方便调试读入,或者文件执行,看个人喜好。
#(4)移动文件的坑
mv -f file1 file2
# 没有-f 会问你overwrite不?然后就停那里。
# 在commands.getstatusoutput(string)里执行时是这个样子的,
# 但是在shell脚本里执行则不会询问,直接覆盖,不管有没有-f
补充
#(1)不想看特别多的内容,怎么办?文件非常大,用im打开会卡怎么办?
# 在查看命令awk或者cat的后面加上"| more"或者"head -n 5"
$ cat file.name | more
$ awk '{print $0}' file.name | head -n 5
# more可以继续查看后续内容;head只能看到前5个
#(3)paste按行拼接
$ paste a b > c 将两份文件按照同行,拼接到一起。不匹配,只是单纯地拼接。
#(4)sort 排序-nr -k2; -t $'\t'
$ sort -nr -k2 file.name 其中-k2是按照第二列排序, n表示按照数字而非默认的字符串,r表示降序,而非默认的升序。
$ sort里的参数设置-t "\t" 是按照tab作为分隔符,但是有时候提示错误 mult \\t这种问题,解决 -t $'\t'搞定。
#(5)获取路径下名字带有时间最新的文件
filename=$(ls path/of/file | tail -1)
#(6)hadoop的mapper.py和reducer.py可以单独用测试用例来调试,这是Python写mapreduce的好处。如果不做shuffle处理,Hadoop平台会自动将mapper输出的key进行排序。
#(7)crontab -e
# 注意lock的使用,避免上个程序未完成,下个程序就进行了覆盖。日志能保留着最好,看情况。
#(8)在awk或者其他处理的后面加上 | sort | uniq 进行排序和去重。
#(9)Xshell使用时,中文显示乱码问题,尤其egerp “中文”file.name
# 首先保证本地的编码与远端的编码一致,查看远端编码$echo $LANG本地设置在工具栏上有个“编码”选项。或者file->属性->terminal->编码。
# 系统的$LANG修改,在文件/etc/sysconfig/i18n中,然后source一下,即可。但是如果是公司统一管理的账户下修改,基本上下次会自动回复原始设置,除非拿到更高权限。
#(10)vim
vim下查看文件编码 :set fileencoding
vim下显示数字行号:set nu/nonu
vim下显示分隔符:set list/nolist
vim支持多种文件编码方式:
在~/.vimrc增加,set fileencodings=ucs-bom,utf-8,cp936,gbk,gb2312
# 以方便打开多种格式的文件,而不至于乱码。
vim 的自动补全,ctrl+n,仅限于本文件内出现过词的补全。
#(11)关闭ssh的命令窗口后,程序继续执行
nohup your-commands
#(12)显示进程
ps -au search -ef | grep "python" 显示用户search 且为Python脚本的进程。
kill num 杀掉进程,num来自上面的那行命令。