LittleQ

爱好:写代码

服务器上有些脚本,执行的参数用到了日期,也就是每天执行一次,日期取当天时间作为参数,当有些时候需要把这些脚本过去一段时间的运行结果重新运行一次时,手动指定脚本日期没有办法大批量执行,需要在shell中写循环,让脚本批量执行.

方法一

以一个小的例子来说:把指定日期时间段内的日期都输出来,看看下面的代码:

1
2
3
4
5
6
7
8
9
10
#! /bin/bash

start_date=20151101
end_date=20151103
start_sec=`date -d "$start_date" "+%s"`
end_sec=`date -d "$end_date" "+%s"`
for((i=start_sec;i<=end_sec;i+=86400)); do
day=$(date -d "@$i" "+%Y-%m-%d")
echo $day
done

看看输出结果:

1
2
3
2015-11-01
2015-11-02
2015-11-03

执行结果是循环输出日期,把需要循环的脚本放在循环里调用,把$day当参数使用即可.如果脚本里面的变量是日期,那就把脚本代码拷贝到循环中间.日期的格式可以按需求自己调整.例如:

1
2
3
4
5
for((i=start_sec;i<=end_sec;i+=86400)); do
day=$(date -d "@$i" "+%Y-%m-%d")
echo $day
sudo /usr/python/ /usr/dev/job.py $day
done

这样就可以把时间参数批量传入脚本.

方法二

但是上面的还是很麻烦,你要记住一天有多少秒,这样也不太容易记住,下面还有另一种方法,注意到时间格式为20151101,这种其实也是一个数字,我们可以让日期按天增加,然后比较日期大小关系:

1
2
3
4
5
6
7
8
9
10
#! /bin/bash

start=20160101
end=20160103

while [ ${start} -le ${end} ]
do
echo ${start}
start=`date -d "1 day ${start}" +%Y%m%d` # 日期自增
done

**备注:**Shell里面的数字大小比较:

1
2
3
4
5
-ne	# 不相等
-gt # 大于
-lt # 小于
-ge # 大于或等于
-le # 小于或等于

方法三

虽然上面的方法二比方法一要好很多,但是好像有个问题,一般日期都是以字符串的形式传入,多半是2016-01-01这种带间隔的方式,这种情况我们是没办法比较的,当然把上面的改一改也能用,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#! /bin/bash

# 先把日期处理成纯数字的格式
start=`date -d "2016-01-01" +%Y%m%d`
end=`date -d "2016-03-01" +%Y%m%d`

while [ ${start} -le ${end} ]
do
echo ${start}
# 假设下面有一个脚本需要2016-01-01格式的日期
bash xxx.sh `date -d "${start}" +%Y-%m-%d`
start=`date -d "1 day ${start}" +%Y%m%d` # 日期自增
done

但是这样感觉好麻烦,为啥循环就只能是数字呢?有没有一种比较通用的循环方式,这个当然有,你可以像下面这样:

1
2
3
4
5
6
7
8
9
10
11
#! /bin/bash

start='2016-01-01'
end='2016-01-03'

while [ "${start}" != "${end}" ]
do
echo ${start}
start=`date -d "1 day ${start}" +%Y-%m-%d` # 日期自增
done

这样就可以循环了,但是记住,start取不到end值,即最后输出的是[start,end),好像Shell里面并没有do...while这种循环,所以最好在循环之前,先做一步处理:

1
end=`date -d "1 day ${end}" +%Y-%m-%d`	# 日期自增

然后再就可以取到两边的边界值了。
**注意:**这样比较的时候,一定要注意while里面的左右条件一定要用""引起来,'不行。

从mysql数据库抽取数据到hadoop时,中间加了一个校验层,发现某天的数据Hive表里的和mysql里的差了一条,查询结果有7万多条,但是就只有一条不一样,最开始的思路是利用sql里的集合做差,即左外连接来过滤出那一条记录,但是由于Hive里是分区数据,查询语句怎么写都不对,后来换了一种思路,将查询结果保存到文件中,然后比较两个文件的不同来判断差了哪一条数据.

具体步骤

  • Hive数据导出到文件

利用到了管道,将结果输入到文件,具体命令为:

1
sudo -uuser_name /home/dev/hive-0.12.0/bin/hive -database dw_subject -e "select idid,create_time from table_name  where (create_time>='2015-10-29 00:00:00' and create_time<='2015-10-29 23:59:59') order by idid;" > subject.txt

注意,最好按照主键来将结果进行排序,因为数据很多,时间也可能有重复的,如果按时间来排序,时间相同的数可能顺序会有差异,7万多数据对比起来还是很麻烦的,所以尽量选不重复的字段排序,反正,最好能够保证排序不存在二义性即可.

  • 利用vim比较两个文件

假设这两个文件是subject.txtsource.txt,命令如下:

1
sudo vim -d source.txt subject.txt

最终的效果如下图所示:
Vim对比效果

假设你已经了解基本的vim使用,并且喜欢在vim下写代码,你需要几个非常好用的插件,可以极大的提升你的工作效率.

插件管理利器

原始的插件管理方法就是下一个插件,拷贝到一个目录下就行了,但是这样有点儿乱,插件管理工具常用的用pathogenVundle.就管理插件而言,不需要太过于关注哪个好,都挺好用的,我使用的就是pathogen,其安装方法详见Ubuntu vim安装markdown插件这篇笔记里的介绍.

常用插件

列举了几个比较常用的插件

  1. nerdtree
  2. snipMate
  3. vim-multiple-cursors

以下所有安装方法都是使用pathogen插件管理器的安装方法,其他方法自行琢磨.

nerdtree插件

1
2
cd ~/.vim/bundle
git clone https://github.com/scrooloose/nerdtree.git

这个插件可以使用vim来打开文件夹,按回车进入文件夹,展开文件夹下面的所有文件,可以用vim的光标控制命令来移动,选择打开某个文件.

snipMate插件

1
2
3
4
5
cd ~/.vim/bundle
git clone https://github.com/tomtom/tlib_vim.git
git clone https://github.com/MarcWeber/vim-addon-mw-utils.git
git clone https://github.com/garbas/vim-snipmate.git
git clone https://github.com/honza/vim-snippets.git

这个工具可以快速,减少重复代码,关于具体的使用,你可以在插件目录bundle/存放插件的snippets目录下找到对应的语言的snippets,并且修改对应的snippets.

vim-multiple-cursors插件

1
2
cd ~/.vim/bundle
git clone https://github.com/terryma/vim-multiple-cursors.git

看名字的意思就是多光标编辑,比如你有个变量,在很多地方被引用了,突然有一天你觉得这个变量名字起的不好,想换一个变量名,这个时候可以使用这个,具体效果如下:
测试代码multiple.py:

1
2
3
4
def hell(poorly_named_var)
poorly_named_var ||= "Nameless"
puts("Hi, " + poorly_named_var)
end

vim-multiple-cursors插件多光标效果
上图的演示过程就是,具体的操作就是将光标移到变量的第一个字母,然后按<Crrl-n>就是增加一个,按<Ctrl-p>就是减少一个。连按三下都选中,然后按c,然后输入name即是上面的效果。

在Ubuntu下使用vim开发,写博客,由于博客是使用markdown写的,之前是使用sublime Text来写markdown,不过还是想完全用键盘,书写更快,决定以后都使用vim来写markdown了.

安装前提

首先要安装vim,没有的话终端安装也方便:

1
sudo apt-get install vim

然后安装插件管理器,有几种方式,就以pathogen为例

1
sudo mkdir -p ~/.vim/autoload ~/.vim/bundle && curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim

注意: 如果执行这个命令报错:

1
curl: (23) Failed writing body (0 != 12140)

这是没有写权限所导致的,可以为三个文件夹赋权限

1
2
3
sudo chmod 777 ~/.vim
cd ~/.vim
sudo chmod 777 autoload bundle

然后在~/.vimrc文件里添加如下内容

1
execute pathogen#infect()

注意: 如果刚装的vim,啥东西也没有加过,可能没有.vimrc文件,需要自己新建

1
sudo vim ~/.vimrc

然后添加如下内容:

1
2
3
execute pathogen#infect()
syntax on
filetype plugin indent on

安装vim-markdown插件

现在假设你的pathogen已经安装好了,安装vim-markdown插件

1
2
cd ~/.vim/bundle
git clone https://github.com/plasticboy/vim-markdown.git

然后重新打开一个*.md文件就可以生效了,注意,打开*.md文件,标题块之间会被折叠,光标跳转到折叠行,按空格就可以展开.

由于是用hexo写博客,还需要对YAML语法,需要在~/.vimrc中添加如下配置:

1
let g:vim_markdown_frontmatter=1

基本的插件安装就这几个步骤,其实也没有很特别的提示功能,只是在写错的时候可以看出来,还有就是按标题折叠成块比较实用。

前段时间安装mysqldb时碰到gcc的编译错误问题,后来看到了网上有人说需要更新gcc编译器,在Ubuntu 14.04下更新gcc也很简单

Ubuntu 更新gcc编译器

  • 首先更新源
1
2
3
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.9 g++-4.9
  • 保留旧的gcc
1
2
3
4
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 10  
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 20
  • 查看配置
1
sudo update-alternatives --config gcc

如下结果:

1
2
3
4
5
  选择       路径        优先级  状态
------------------------------------------------------------
* 0 /usr/bin/gcc-4.9 20 自动模式
1 /usr/bin/gcc-4.8 10 手动模式
2 /usr/bin/gcc-4.9 20 手动模式

可以手动选择使用哪个版本,由于我们把gcc-4.9设置的优先级最高,所以默认就是使用的高版本的,对于g++同样.

最近在做数据仓库的迁移工作,之前数据仓库的数据都是用的shell脚本来抽取,后来换了python脚本.
但是在把数据抽取存放到hadoop时,出现了一个问题:
由于数据库字段很多,提前也不知道数据库字段会存储什么内容,hive建表是以\t\n做分隔,这就导致了一个问题,如果mysql字段内容里面本身含有\t\n,那么就会出现字段错位情况,并且很头疼的是mysql有100多个字段,也不知道哪个字段会出现这个问题.
shell脚本里的做法是在需要抽取的字段上用mysql的replace函数对字段进行替换,例如,假设mysql里的字段是column1 varchar(2000),那么很可能就会出现有特殊字符的情况,在查询的sql语句里加上

1
select replace(replace(replace(column1,'\r',''),'\n',''),'\t','')

之前一直是这么干的,但是这样写sql特别长,特别是有100多个字段,也不知道哪个有特殊字符,只要都加上.
所以在python中对字段不加处理,最终导致hive表字段对应出现偏差,所以在python里从mysql查询到的字段在写到文件之前需要对每个字段进行过滤处理

看个例子,我就以mysql测试为例,首先建一张测试表

1
2
3
4
5
6
7
8
CREATE TABLE `filter_fields` (
`field1` varchar(50) DEFAULT NULL,
`field2` varchar(50) DEFAULT NULL,
`field3` varchar(50) DEFAULT NULL,
`field4` varchar(50) DEFAULT NULL,
`field5` varchar(50) DEFAULT NULL,
`field6` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

有六个字段,都是varchar类型,插入新数据可以在里面插入特殊字符.简单插入条数据测试看看:

1
2
3
4
5
6
7
8
insert into filter_fields(field1,field2,field3,field4,field5,field6) VALUES
('test01','test02','test03','test04','test05','test06');
insert into filter_fields(field1,field2,field3,field4,field5,field6) VALUES
('test11\ntest11','test12\n\n','test13','test14','test15','test16');
insert into filter_fields(field1,field2,field3,field4,field5,field6) VALUES
('test21\ttest21','test22\ttest22\ttest22','test23\t\t\t','test4','test5','test6');
insert into filter_fields(field1,field2,field3,field4,field5,field6) VALUES
('test21\rest21','test22\r\rest22\r\rest22','test23\r\r\r','test4','test5','test6');

其中数据里插入的特殊字符,可能连在一起,也有不连在一起的.

python测试代码:

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
42
43
44
45
46
47
48
49
50
# coding=utf-8

import MySQLdb
import sys

db_host = '127.0.0.1' # 数据库地址
db_port = 3306 # 数据库端口
db_user = 'root' # mysql用户名
db_pwd = 'yourpassword' # mysql用户密码,换成你的密码
db_name = 'test' # 数据库名
db_table = 'filter_fields' # 数据库表

# 过滤sql字段结果中的\t\n
def extract_data(table_name):
try:
conn = MySQLdb.connect(host=db_host, port = db_port, user=db_user,
passwd = db_pwd, db = db_name, charset = "utf8")
cursor = conn.cursor()
except MySQLdb.Error, e:
print '数据库连接异常'
sys.exit(1)

try:
sql = 'select * from %s;'%(table_name)
cursor.execute(sql)
rows = cursor.fetchall()

print '====字段未过滤查询结果===='
for row in rows:
print row

print '====字段过滤之后结果===='
rows_list = []
for row in rows:
row_list = []
for column in row:
row_list.append(column.replace('\t', '').replace('\n', '').replace('\r', ''))
rows_list.append(row_list)
print rows_list[-1] # [-1]表示列表最后一个元素
return rows_list
except MySQLdb.Error, e:
print '执行sql语句失败'
cursor.close()
conn.close()
sys.exit(1)

if __name__ == '__main__':
print 'begin:'
rows = extract_data(db_table)
pass

看看输出结果:

1
2
3
4
5
6
7
8
9
10
====字段未过滤查询结果====
(u'test01', u'test02', u'test03', u'test04', u'test05', u'test06')
(u'test11\ntest11', u'test12\n\n', u'test13', u'test14', u'test15', u'test16')
(u'test21\ttest21', u'test22\ttest22\ttest22', u'test23\t\t\t', u'test4', u'test5', u'test6')
(u'test21\rest21', u'test22\r\rest22\r\rest22', u'test23\r\r\r', u'test4', u'test5', u'test6')
====字段过滤之后结果====
[u'test01', u'test02', u'test03', u'test04', u'test05', u'test06']
[u'test11test11', u'test12', u'test13', u'test14', u'test15', u'test16']
[u'test21test21', u'test22test22test22', u'test23', u'test4', u'test5', u'test6']
[u'test21est21', u'test22est22est22', u'test23', u'test4', u'test5', u'test6']

可以看到,制表符,换行符,回车都被过滤了.
**建议:**最后说点题外话,不要小视\r,回车符.很多人以为回车符就是换行符,其实不是的,\r表示回车符,\n表示新行.之前代码里其实是过滤掉了\t\n的,但是抽取的数据还是不对,后来看了源码之后才发现,原来是没有过滤\r,就这个不同导致了很多数据抽取不对.

在日常工作开发中,都是登陆跳板机然后再登陆开发机或者在线服务器,有时候需要把一个本地文件上传到服务器,例如服务器缺少某个字体,通常是本地机下载字体然后上传到服务器.也有时候需要把服务器上的某个文件拷贝到本地,例如某个日志或者结果等.这个时候scp命令登场了.

scp命令使用

准备条件

假设你的用户名是zhang.san
跳板机地址:redirector.machine.com
目标机器地址:target.machine.com
本机文件:/home/zhang.san/1.txt
目标机器文件:/home/dev/www/log/test.log

注意: 由于是跳板机,所以会有很多人登陆,每个人在跳板机上都有一个以自己名字命名的目录,例如/home/zhang.san/

本地上传到服务器

  • 上传文件到跳板机
1
2
3
➜  ~  scp 1.txt zhang.san@redirector.machine.com:~
Enter PASSCODE:"此处可能要输入密码"
1.txt 100% 10 0.0KB/s 00:00
  • 登陆跳板机查看
1
2
3
4
5
ssh zhang.san@redirector.machine.com
Enter PASSCODE:"输入密码处"
Last login: Tue Oct 27 19:16:47 2015 from 10.86.108.97
[zhang.san@redirector.machine.com ~]$ ls
1.txt

再在跳板机上进行同样的操作上传到服务器即可.

服务器下载到本地

在本地机器上执行下面命令

1
scp zhang.san@redirector.machine.com:1.txt ./ 

注意这个命令不是在跳板机,而是在本地机器上执行.

其实前面的是比较复杂的,如果单纯的只是想从服务器上上传东西,可以使用一个简单的命令:

1
python -m SimpleHTTPServer 端口号

这个命令可以把执行这个命令的目录变成一个服务器的目录,可以直接用http下载,pythons服务器上一般是安装了的,没有的话就不能这么用了。

在Ubuntu下,由于缺少宋体,导致中文路径出现乱码,解决办法是先下载字体,然后在IDEA中设置使用宋体即可。
乱码有几种情况,

编辑器以及调试信息乱码

解决方案,选择File-->settings-->Editor-->File Encoding
IDEA 中设置默认字符编码
如上图所示,两个编码都选择UTF-8,这样可以保证以后新建的文件编码方式,防止乱码。

IDEA 其他窗口乱码

如下图所示:
IDEA 中窗口乱码
出现这样的原因是linux系统提供的字体不支持中文的显示,在idea中,默认的是ubuntu字体,该字体并不支持中文显示。因此,还需要自己下载一个支持中文显示的字体。

1
sudo cp Downloads/simsun.ttf /usr/share/fonts
  • 重启IDEA,设置字体
    重启idea,然后选择File->settings->Appearance & Behavior->Appearance.如下所示:
    IDEA中设置simsun字体
    在右边勾选上Override default fonts by(....),并在Name选项中选择刚刚添加的SimSun字体。

Linux下使用VPN十分简单,只需要安装一软件即可。

  • 安装网络挂件vpnc
1
sudo apt-get install vpnc
  • 找到公司的默认配置文件xxx_common.pcf,使用命令将其转化成对应的配置文件
1
sudo pcf2vpnc Documents/xxx_common.pcf default.conf
  • 替换配置文件
1
2
sudo chmod 777 /etc/vpnc 
sudo cp default.conf /etc/vpnc
  • 更改配置文件中的账户Xauth username
1
sudo vim /etc/vpnc/default.conf
  • 连接VPN
1
sudo vpnc-connect

备注: 关闭连接用sudo vpnc-disconnect

之前把Ubuntu的默认的源替换了,速度有点慢,现在替换回来
在命令行下修改,修改/etc/apt/sources.list,内容修改如下:

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# deb cdrom:[Ubuntu-Kylin 14.04.1 LTS _Trusty Tahr_ - Release amd64 (20140722.1)]/ trusty main multiverse restricted universe

# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://cn.archive.ubuntu.com/ubuntu/ trusty main restricted
deb-src http://cn.archive.ubuntu.com/ubuntu/ trusty main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb http://cn.archive.ubuntu.com/ubuntu/ trusty-updates main restricted
deb-src http://cn.archive.ubuntu.com/ubuntu/ trusty-updates main restricted

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://cn.archive.ubuntu.com/ubuntu/ trusty universe
deb-src http://cn.archive.ubuntu.com/ubuntu/ trusty universe
deb http://cn.archive.ubuntu.com/ubuntu/ trusty-updates universe
deb-src http://cn.archive.ubuntu.com/ubuntu/ trusty-updates universe

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## multiverse WILL NOT receive any review or updates from the Ubuntu
## security team.
deb http://cn.archive.ubuntu.com/ubuntu/ trusty multiverse
deb-src http://cn.archive.ubuntu.com/ubuntu/ trusty multiverse
deb http://cn.archive.ubuntu.com/ubuntu/ trusty-updates multiverse
deb-src http://cn.archive.ubuntu.com/ubuntu/ trusty-updates multiverse

## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
deb http://cn.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://cn.archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse

deb http://security.ubuntu.com/ubuntu trusty-security main restricted
deb-src http://security.ubuntu.com/ubuntu trusty-security main restricted
deb http://security.ubuntu.com/ubuntu trusty-security universe
deb-src http://security.ubuntu.com/ubuntu trusty-security universe
deb http://security.ubuntu.com/ubuntu trusty-security multiverse
deb-src http://security.ubuntu.com/ubuntu trusty-security multiverse

## Uncomment the following two lines to add software from Canonical's
## 'partner' repository.
## This software is not part of Ubuntu, but is offered by Canonical and the
## respective vendors as a service to Ubuntu users.
# deb http://archive.canonical.com/ubuntu trusty partner
# deb-src http://archive.canonical.com/ubuntu trusty partner

## Uncomment the following two lines to add software from Ubuntu's
## 'extras' repository.
## This software is not part of Ubuntu, but is offered by third-party
## developers who want to ship their latest software.
# deb http://extras.ubuntu.com/ubuntu trusty main
# deb-src http://extras.ubuntu.com/ubuntu trusty main
0%