CI中加入生成一维码的lib

给朋友做的一个项目,其中用到生成条形码,主要用到了http://www.barcodephp.com/这个开源的类库,把它集成到了CI里面,代码和集成方法稍后给出来
1.到http://www.barcodephp.com/en/download下载包
2.解压后,将class文件夹放到application/libraries下面,可以改名为barcode,如果需要用他字体的话,font也放到你放字体的地方
3.application/libraries下面新建Barcode.php

<?php
include 'barcode/BCGFontFile.php';
include 'barcode/BCGColor.php';
include 'barcode/BCGDrawing.php';

include 'barcode/BCGcode39.barcode.php';

class Barcode {
    public $colorFront;
    public $colorBlack;
    public $font;

    function __construct(){
        $this->colorBlack = new BCGColor(255,255,255);
        $this->colorFront = new BCGColor(0,0,0);
//        $this->font = new BCGFontFile('/assets/font/Arial.ttf', 18);//需要字体在这里指定
    }

    public function genBarcode($text) {
        $code = new BCGcode39();

        $code->setScale(2); // Resolution
        $code->setThickness(30); // Thickness
        $code->setForegroundColor($this->colorFront); // Color of bars
        $code->setBackgroundColor($this->colorBlack); // Color of spaces
//        $code->setFont($this->font); // Font (or 0)
        $code->parse($text); // Text

        $drawing = new BCGDrawing('', $this->colorBlack);
        $drawing->setBarcode($code);
        $drawing->draw();

        header('Content-Type: image/png');


        $drawing->finish((BCGDrawing::IMG_FORMAT_PNG));
    }
}

调用的时候,直接load这个barcode,然后调用genBarcode即可

计算web访客的一个会话识别算法的php实现

QQ截图20140506173210

最近在做公司的BI系统,由于很多东西都是探索阶段,做起来遇到很多的问题,下面这个是其中一个计算一次访问会话的实现,还待优化和改进

/**
 * @param $data array(key=>array((int)view_time,url,referer)) order by value asc
 * @param $threshold
 * @param $delta
 * @return boolean
 */
function uvAlgorithm($data, $threshold, $delta) {
    $stack = array();
    $rangeDown = $data[0]['view_time'];
    $vid = md5($rangeDown);
    $rangeUp = $data[0]['view_time'] + $threshold;
//    echo $rangeDown . '~' . $rangeUp . "\n";
//    print_r($data);
    foreach ($data as $k=>$v) {
        if ($k == 0) {
            updateVisitId($v['id'], $vid);
            $stack[] = $v['url'];
            continue;
        }
        if ($v['view_time'] >= $rangeDown && $v['view_time'] < $rangeUp) {
            if (in_array($v['referer'], $stack) || ($data[$k]['view_time'] - $data[$k - 1]['view_time'] < $delta)) {
                $stack[] = $v['url'];
                updateVisitId($v['id'], $vid);
            }
            else {
                updateVisitId($v['id'], md5($v['view_time']));
            }

        }
        else {
            $temp = array_splice($data, $k);
//            print_r($temp);
//            print_r($data);
//            print_r($stack);
            $stack = array();
            if (empty($temp)) {
                return false;
            }
            else {
                uvAlgorithm($temp, $threshold, $delta);
            }
        }
    }
}

也谈rsync

目前工作的公司上线是通过rsync来同步代码的,前公司则是用ftp发布代码到预发布环境然后再用rsync实时同步到线上环境,今天就来看下rsync这个强大的工具

what’s rsync

rsync(remote synchronization)是*nix下一款同步软件,用于远程同步,备份文件,当然也可以本地做同步备份操作。

rsync 可以在中断之后恢复传输;它只传输源文件和目标文件之间不一致的部分;rsync 可以执行完整备份或增量备份。更棒的是,在所有风格的 UNIX 上都可以使用 rsync,包括 Mac OS X,所以很容易连接任何系统。

how to use rsync

shell模式(本地模式)

先来看下目录结构

[root@localhost tmp]# tree -L 2
.
├── rsync1
│   ├── 1.txt
│   ├── a.txt
│   ├── c.txt
│   └── v.txt
├── rsync2
│   └── 1.txt

要将rsync1中的内容完全同步到rsync2中

[root@localhost tmp]# rsync -avz rsync1/ rsync2
sending incremental file list
./
a.txt
c.txt
v.txt

sent 189 bytes  received 72 bytes  522.00 bytes/sec
total size is 0  speedup is 0.00

远程shell模式

[root@localhost tmp]# rsync -avz rsync1/ root@192.168.22.81:/tmp
root@192.168.22.81's password: 
sending incremental file list
./
1.txt
a.txt
c.txt
v.txt

sent 225 bytes  received 91 bytes  9.16 bytes/sec
total size is 0  speedup is 0.00

列表模式

[root@localhost tmp]# rsync rsync1/
drwxr-xr-x        4096 2014/02/20 13:42:21 .
-rw-r--r--           0 2014/02/18 16:41:47 1.txt
-rw-r--r--           0 2014/02/20 13:42:21 a.txt
-rw-r--r--           0 2014/02/20 13:42:21 c.txt
-rw-r--r--           0 2014/02/20 13:42:21 v.txt

这个和ll命令是一样的

服务器模式

在rsyncd下有下列rsync服务的配置

[root@localhost rsyncd]# pwd && ll
/etc/rsyncd
total 12
-rw-r--r-- 1 root root 808 Feb 19 16:21 rsyncd.conf
-rw-r--r-- 1 root root  36 Feb 19 15:10 rsyncd.motd
-rw------- 1 root root  12 Feb 19 15:10 rsyncd.secrets

rsyncd.conf是主要配置文件,

pid file = /var/run/rsyncd.pid  
port = 873
#address = *
uid = root  
gid = root  
use chroot = yes
read only = yes

#limit access to private LANs
hosts allow=*
#hosts deny=*

max connections = 5
motd file = /etc/rsyncd/rsyncd.motd

#This will give you a separate log file
log file = /var/log/rsync.log

#This will log every file transferred - up to 85,000+ per user, per sync
#transfer logging = yes

log format = %t %a %m %f %b
syslog facility = local3
timeout = 300

[root_tmpTrans]  
path = /tmp/rsnctrans
list=yes
ignore errors
auth users = root
secrets file = /etc/rsyncd/rsyncd.secrets
comment = balabala
exclude =   .git/ .svn/

rsyncd.secrets是执行同步、备份的账号,格式为user:password

root:123456

rsyncd.motd是执行时的欢迎信息(message of the day)

hi---------------------------------

现在我们启动rsync服务

rsync --daemon --config=/etc/rsyncd.conf

现在从另一台机器上看这个守护进程

root@ubuntu:/tmp# rsync 192.168.22.81::
hi---------------------------------

root_tmpTrans   balabala

指定模板名称

root@ubuntu:/tmp# rsync 192.168.22.81::root_tmpTrans
hi---------------------------------

Password: 
drwxr-xr-x        4096 2014/02/19 16:43:38 .
-rw-r--r--           0 2014/02/19 15:13:19 a.txt
-rw-r--r--           0 2014/02/19 16:43:38 c.txt
-rw-r--r--           0 2014/02/19 16:37:40 v.txt

注意上面两个例子,访问服务器模式的时候,有两个冒号
此时,直接利用rsync服务器模式,来备份,同步文件,和前面的模式类似

联系上crontab,写好需要的shell脚本,将备份和同步自动话,定时执行,这样就可以应用到更多的场景中。

题外话:1.这篇文章已经在草稿箱躺了2个月了,OMG.2.今天装了markdown插件,第一次用markdown写wordpress,有些地方不是很好用.3.最近心情不好,状态极差.

WEB开发中的请求调试小记

这边就讲一个小发现,以后不定期补充。让调试工具记录下所有的请求,包括各种跳转之前的请求,以前只知道用IE的httpwatch插件来调试,直到周五看了王益同学用firebug调试的时候在net那个tab下有个persist的选项,惊呼发现了新大陆,原来还可以这样!!不用firebug好多年,一直用的chrome做开发,一直都是找chrome插件的来调试跳转请求。。蛋疼。。。然后就果断google了下,其实chrome也有同样的功能,就是在network那个标签下的大黑点preserve log upon navigation,为什么我以前google的时候没找到呢?而且,IE9的dev tools也是有这个功能的!不详述。。

今日两坑

坑1:

$a = 'test';
echo $a['bdd'];

得到结果

t

一个字符串,把它当成数组并取它一个不存在的键值,得到的是第一个字符。今天写一个方法的时候,返回结果可能是字符串也可能是数组,调用这个方法的时候用数组中的某个值来判断,无疑是错的!

坑2:

在post的时候有大量的数据,发现post不过去,原来php在5.3.9以后的版本中加入了最大post数量的限制,默认是1000条,可以在php.ini中找到该项

max_input_vars来做修改。

为什么在5.3.9中加入这个参数?这个就要提到hash冲突的一个漏洞了,这个漏洞在没patch的低版本php中存在,包括java等各种语言中存在。hash表是一种良好的数据结构,当数据被精心构造过之后,会使hash表降级成一个链表结构,在查询数据的时候每次都会发生hash冲突,一次命中率极低,大大降低了效率,这就使得单机DDOS攻击成为可能。因此加入这个post数量限制限制了服务器接收的post数据,即使post过来默认的1000个数据都能精确的造成hash冲突,那么也是在服务器能够承受的范围内了。

可以参考:

参考1

参考2

sed的模式空间和暂存空间

关于sed(stream editor):

————sed是一个批处理(非交互式)编辑器。它可以变换来自文件或者标准输入的输入流。它常被用作管道中的过滤器。由于sed仅仅对其输入扫描一次,因此它比其他交互式编辑器(如ed)更高效。大多数linux发行版都提供了GNU sed,Mac OS X提供了BSD sed。『A Practical Guide to Linux Commands, Editors, and Shell Programming, chapter 13』

sed和awk一样,都是经典的linux神器,网上有大量相关教程,比如很不错的左耳朵耗子博客。今天想记录下之前并没有理解透的暂存空间和模式空间相关的操作(感觉自己智商一直在下降- -)。

模式空间[pattern space]是一个缓冲区,该缓冲区最初保存sed刚刚从输入中读取的行。在将数据放入暂存空间之前,他的内容为空。

暂存空间[hold space]也是一个缓冲区,该缓冲区可以在操作模式空间中的数据时用来暂存数据。

几个命令:

g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
G: 将hold space中的内容append到pattern space\n后
h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
H: 将pattern space中的内容append到hold space\n后
x: 交换pattern space和hold space的内容

看这样一个文件

aladdin@ubuntu:~/tmp$ cat sedtext 
line one
line two
line three

我们看这样一条命令

aladdin@ubuntu:~/tmp$ sed '2,$G;h;$!d' sedtext 
line three
line two
line one

我们来分析一下:

首先,这边sed对sedtext有3个命令的操作

2,$G:从第二行到最后一行执行G命令

h:执行h命令

$!d:删除除了最后一行的所有行

然后看其中具体操作

第一步,sed扫描到第一行,直接执行第二个命令,将模式空间中的内容拷贝到暂存空间中,此时模式空间中是line one,暂存空间中是line one,然后执行第三个命令,删除了模式空间中的第一行,此时模式空间中为空,暂存空间中为line one,

第二步,sed扫描到了第二行,会执行第一个命令G了,此时模式空间中是line two,暂存空间中是line one,G将换行符和暂存空间内容追加到模式空间中,此时模式空间是line two\nline one,暂存空间是line one,然后执行第二个命令,将模式空间中的内容拷贝到暂存空间中,此时模式空间不变,暂存空间为line two\nline one,执行第三个命令之后,模式空间为空,暂存空间为line two\nline one

第三步,sed扫描到第三行,会执行第一个命令G,模式空间为line three,暂存空间是line two\nline one,执行之后模式空间是line three\nline two\nline one,暂存空间是line two\nline one,然后h命令,模式空间不变,暂存空间line three\nline two\nline one然后不执行第三条命令,ok,结束,打印的就是最后模式空间爱你中的内容line three\nline two\nline one

我们可以看下sed '1!G;h;$!d' sedtext也可达到同样效果。

团队项目中的一些思考

最近在公司参与的一个项目,项目开发过程中遇到很多的问题,也开了无数的会议,包括各种需求会议,总结会议等等,现在算是进入了尾声了,不过本来预计今天上线的依然没能上线,虽然我内心感到非常遗憾,但是我依然向领导吐槽了许多不满。

开篇之前,对于项目开发,我要申明下我的几个观点。我这几个观点的前提条件是,在中小型项目中!

1.不需要产品经理

2.不需要测试

3.不需要专职的运维

4.不许要专职的DBA

————关于产品经理

我数次的在知乎上搜寻关于产品经理这一角色的信息,很想获取一些产品经理相关的知识,结果让我很失望。作为互联网界的一个新人(2.5年的开发经验),我所接触到的产品经理,无非是写个PRD,画个原型图,然后催催进度。仅此而已,至于说什么产品创新,ok,在国内不适合谈这个事。好吧,我承认我从主观上已经贬低了产品经理存在的价值。我依稀记得第一次听说产品经理这个词的时候,是一篇文章中提到的,那边文章是对马化腾的采访,马化腾说自己只是一个产品经理而已。具体年月已经不清晰了。

诚然,随着人类社会的进步,社会分工逐渐细化,产品经理这个角色的出现是有其合理性的(我认为在大型项目中此角色的存在是有必要性的,我心目中什么是大项目?比如我的第一家公司中接的摩托罗拉面向整个欧洲的一个通信项目,这个项目的总参与人数是2000+,参与者遍及北美,欧洲,印度和中国,耗时两年多。当然我没有能参与这个项目)。排除我待过的其中一家公司没有产品经理(我们开发要自己写function specification, development plan.),另外公司我都曾经问过产品经理:你们每天的工作是什么?核心答案基本就这3个:写需求文档,画原型,跟进度。

国内互联网公司的产品开发流程基本也差不多:当产品经理从客户或者运营那里收集到了需求,规模烧大点的话,会有BRD的移交,加上自己的一些“微创新”,好吧,很多需求是从BOSS那里来的。然后产品经理再和开发过需求,递交PRD并评审。这其中如果产品经理和需求方的理解有出入,再加上产品经理和开发的理解有出入,那么这边的沟通导致的问题是很大的。ok,多了产品经理,沟通成本上去了,项目风险增加了!为了减少风险,应该是有一个需求确认会议的,但是这个环节,很多公司都没有的,比如我这次参与的项目。然后到了开发手里,首先开发要根据业务逻辑关系确定数据结构,确定开发方案,并定下开发计划和预估开发时间。来看看我现在接手的那些项目,都是在PRD移交的时候,就尼马问我们开发,要!时!间!啊!有时候PRD是没有的,有时候PRD尼马几十上百页doc啊!原型会有一个,尼马很多链接的交互都没有啊!我艹!好了,冷静,不吐槽!反思下,我们做一个CMS性质的项目,做一个app,服务端连通的项目,做一个网站的改版,3-5人的开发小团队……需要这样的流程么?如果只是由开发负责整个过程,会不会能够更高效的执行呢?由开发和设计收集需求,设计人员自己出设计搞,开发自己定方案,然后去确定数据结构,进行开发。不仅减少了沟通成本,而且,开发能更深入的理解业务。何乐而不为?国内有没有这样的公司?我知道的有百姓网,豌豆荚。就我这次的项目来说,产品经理不参与开发,但是产品经理却定方案,直接导致了我这次参与的项目,需要在提交测试的时候由开发来手动往数据库写数据这种滑天下之大稽的事情的发生!PS:产品经理为什么会存在?知乎答案

————关于测试

不得不说我所在的第一家公司是中国的一支开发界的正规军,只可惜它是一家外包公司。公司有专职的QA(quality assurece)团队,他们负责公司项目的黑盒白盒测试,写大量的代码(test case),涵盖各种语言。任何一个测试转到开发都是分分钟的事情,这是酷壳博主口中的QA,当然,如果现在公司有这样的QA,幸甚!我们回到现实,看看国内大部分的互联网公司的测试是什么样的?懂代码的凤毛麟角,每天测试的工作就是,浏览器兼容性,各个功能点的黑盒测试,ok,稍微好点的有边界测试。我曾经在上家公司遇到过最奇葩的测试是什么情况?清!浏!览!器!缓!存!都!不!会!啊!更不要说清dns缓存,造cookie神码的了!!!连这些都需要沟通,更别提数据层面一些问题的沟通导致的成本和风险增加了!我理想的测试便是前面酷壳博主的文章中的情形了。

————关于运维和DBA

首先,我想问问各位如果在一个500人以内的小公司里面,是否有专职的运维和DBA呢?他们忙吗(一天上线十个需求的除外)?就我目前来看,我们开发完全可以吧运维和dba的工作做掉,管理mysql一些账户权限,优化一些sql,OMG这些需要DBA么?看看阿里的DBA都在做什么吧!其实,或许我们需要的只是一个mysql顾问。运维?管理个几十台服务器?搭个集群?配一些运行环境?配置一些代理?Rsync同步下代码?维护代码版本库?这些按道理都是开发分内的事情啊!运维该干什么?当公司项目上到500台服务器,再提运维这个岗位好么?

In a word,中小型项目中,如果开发团队中都是技能合格,有责任心有执行力的同学,完全能够高效的完成项目!作为一个web开发者,个人认为,基本的前端布局要懂的,js效果要会写的,闭包,原型,要理解的!ajax神码的不用说了,http请求流程要清楚的,后端不提,mysql基本的管理能力要有的,基本的使用和常用的函数要会的;主流的debian,红帽系服务器,搭个环境,定位个log,vim操作编辑个文件,这些都应该情理之中要掌握的。我还想强调一点,作为一个程序员,要有责任心,对自己开发过的功能,项目负责到底!你的负责会减轻很多他人工作!不要做码农,要做professional software develop engineer !

写在最后:我很期望我所在的团队,可以做一个短小精干,能独立跟项目,让PM,让DBA,让OP, 让QA都靠边站的团队。Yes, we can!!!

PS1:年内有个想法,在公司内分享下我对web开发的一个愿景和实现:用git做版本控制,xdebug做debug工具,phpDocument做文档工具,测试驱动开发,phpunit写Unit test,用Phing来做自动构建,jenkins/travis来做持续集成和自动部署。。

PS2:各位可以随意喷,尤其是产品狗,博主还年轻,不足之处,可以很快改正!

PS3:维基百科的软件开发流程

CodeIgniter中的配置类

CI中的配置文件默认都在application/config/路径下,当然也可以在你的自定义路径下,其中config.php是自动加载的,如果需要程序初始化的时候自动加载你需要的配置文件,那么在autoload.php中,在$autoload[‘config’] = array();中加入你需要的文件名即可。

在自定义配置文件中需要注意的一点就是,你所有的配置数据都需要放到全局的配置变量$config中,比如在application/config/路径下,新建了一个配置文件customized.php.内容如下:

$customize = array(
    'customize1' => 1,
    'customize2' => 2,
    'customize3' => 3,
    'customize4' => 4,
    'customize5' => 5,
    'customize6' => 6,
    'customize7' => 7,
);

假定手动加载该文件$this->config->load(‘customized’);会发现有如下报错

Your application/config/sns.php file does not appear to contain a valid configuration array.

提示这个配置文件没有包含一个合法的配置数组,那么合法的配置数组是怎样的呢,通过看核心配置类源码system/core/Config.php中的load方法

/**
	 * Load Config File
	 *
	 * @access	public
	 * @param	string	the config file name
	 * @param   boolean  if configuration values should be loaded into their own section
	 * @param   boolean  true if errors should just return false, false if an error message should be displayed
	 * @return	boolean	if the file was loaded correctly
	 */
	function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
	{
		$file = ($file == '') ? 'config' : str_replace('.php', '', $file);
		$found = FALSE;
		$loaded = FALSE;

		$check_locations = defined('ENVIRONMENT')
			? array(ENVIRONMENT.'/'.$file, $file)
			: array($file);

		foreach ($this->_config_paths as $path)
		{
			foreach ($check_locations as $location)
			{
				$file_path = $path.'config/'.$location.'.php';

				if (in_array($file_path, $this->is_loaded, TRUE))
				{
					$loaded = TRUE;
					continue 2;
				}

				if (file_exists($file_path))
				{
					$found = TRUE;
					break;
				}
			}

			if ($found === FALSE)
			{
				continue;
			}

			include($file_path);

			if ( ! isset($config) OR ! is_array($config))
			{
				if ($fail_gracefully === TRUE)
				{
					return FALSE;
				}
				show_error('Your '.$file_path.' file does not appear to contain a valid configuration array.');
			}

			if ($use_sections === TRUE)
			{
				if (isset($this->config[$file]))
				{
					$this->config[$file] = array_merge($this->config[$file], $config);
				}
				else
				{
					$this->config[$file] = $config;
				}
			}
			else
			{
				$this->config = array_merge($this->config, $config);
			}

			$this->is_loaded[] = $file_path;
			unset($config);

			$loaded = TRUE;
			log_message('debug', 'Config file loaded: '.$file_path);
			break;
		}

		if ($loaded === FALSE)
		{
			if ($fail_gracefully === TRUE)
			{
				return FALSE;
			}
			show_error('The configuration file '.$file.'.php does not exist.');
		}

		return TRUE;
	}

加载自定义配置的这个方法,非要在自定义配置文件中找到$config这个变量才罢休,否则就是不合法的。所以,只需要在我们原来的自定义配置文件加上一行就ok了,如下

$customize = array(
    'customize1' => 1,
    'customize2' => 2,
    'customize3' => 3,
    'customize4' => 4,
    'customize5' => 5,
    'customize6' => 6,
    'customize7' => 7,
);
$config['customize'] = $customize;

如此写法,不免觉得有些僵硬。。。

PS:现在Ellislab已经放弃了CI的维护,希望找到到下一个维护CI的组织,CI3.0已经看不到希望了。

如何用linux神器AWK查询开房记录

前一段时间火热的2000w开房记录,加菲同学给了我一份,话说当初拿到文件的时候,我二话没说,写了一个php脚本,在windows下往mysql插,不曾想,插了1w余条便502而死。而后又改进脚本,在cli模式下,开了11个窗口,跑了十几分钟的样子终于都入了mysql,但是在未建索引的情况下,搜索varchar类型的字段,每次搜索都超过2分钟。如此低效,令人发指。正好近期学习完awk章节,期间拿记录文件来测试,效率极高,今日总结此文,权当巩固知识之用了,如若看官能从此文习得一招两式,荣幸之至。

关于AWK,介绍如下:

AWK的作者(Alfred V.Aho && Peter J.Weinberger && Brain W.Kernighan),他是一种模式扫描与处理语言,搜索一个或者多个文件,以查看这些文件中是否存在匹配指定模式的记录(通常是文本行)。每次发现匹配的记录时,它通过执行动作的方式(比如将该记录写到标准输出或者将某个计数器递增)来处理文本行。与过程语言相反,AWK属于数据驱动语言:用户描述想要处理的数据并告诉AWK当它发现这些数据时如何处理他们。

我手里拿到的是一份2000w开放记录的csv文件压缩包(对于其完整性不要太抱期望),因为此次泄漏的记录本身只是部分时间段的部分文件而已。文件列表如下

-rw-------  1 aladdin aladdin 303M Jun 27 21:23 1000W-1200W.csv
-rw-------  1 aladdin aladdin 294M Jun 27 21:30 1200W-1400W.csv
-rw-------  1 aladdin aladdin 333M Jun 27 20:24 1-200W.csv
-rw-------  1 aladdin aladdin 306M Jun 27 21:43 1400W-1600W.csv
-rw-------  1 aladdin aladdin 296M Jun 27 22:07 1600w-1800w.csv
-rw-------  1 aladdin aladdin 285M Jun 27 22:20 1800w-2000w.csv
-rw-------  1 aladdin aladdin 297M Jun 27 20:32 200W-400W.csv
-rw-------  1 aladdin aladdin 297M Jun 27 20:49 400W-600W.csv
-rw-------  1 aladdin aladdin 295M Jun 27 21:02 600W-800W.csv
-rw-------  1 aladdin aladdin 297M Jun 27 21:15 800W-1000W.csv
-rw-------  1 aladdin aladdin 7.2M Jun 27 22:25 last5000.csv

如果你迫不及待想用你的姓名,生日,身份证号等等信息查询你是否在记录中,一条语句便可

awk '/王X/ && /靖江/' 1000W-1200W.csv 1200W-1400W.csv 1-200W.csv 1400W-1600W.csv 1600w-1800w.csv 1800w-2000w.csv 200W-400W.csv 400W-600W.csv 600W-800W.csv 800W-1000W.csv last5000.csv

这语句很易懂,就是在这些数据文件中将匹配模式  ‘/王X/ && /靖江/’  的记录打印出来,我们先来看结果,10秒多的时间,搜寻近3G的文件内容之后,cpu和内存占用没有明显的数据变化,结果已然如列:

王X,,,ID,321XXXXXXXXXXX5028,F,19xxxxxx,江苏省靖江市XXXXXX,,F,,CHN,32,3201,,,,,,,,,,汉,,,,,,,0,2012-12-29 17:50:49,13773207
王X,,,ID,321XXXXXXXXXXX5218,M,19xxxxxx,江苏省靖江市XXXXXXXXXXXX,,F,,CHN,32,321282,,,,,,,,,,汉,,,,,,,0,2012-6-6 13:52:38,14885090
王X,,,ID,321XXXXXXXXXXX043X,M,19xxxxxx,江苏省靖江市XXXXXXXXXXX,,F,,CHN,32,3201,,,,,,,,,,汉,,,,,,,0,2011-1-19 3:05:42,5593856
王X,,,ID,321XXXXXXXXXXX1817,M,19xxxxxx,江苏省靖江市XXXXXXXXXX,,F,,CHN,32,320105,,,,,,,***********,,,汉,,,,,,,0,2011-6-12 13:52:38,8115281
王X,,,ID,320XXXXXXXXXXXX92X,F,19xxxxxx,江苏省靖江市XXXXXXXXXXXX,,F,,CHN,32,3201,,,,,,,,,,汉,,,,,,,0,2011-9-14 7:21:50,9908197

姓名,身份证号,性别,生日,户口住址,开房时间……一目了然,我们来分析下这个语句

awk '/pattern/' file-lists  # 这里的pattern支持与/或等各种逻辑,斜杠表示:这里是个正则表达式

其实这里是有个缺省动作{print}的,打印(即复制到标准输出)匹配出的记录,原理了然。

 

为方便实验,我们下面拷贝下last5000.csv这个文件,用拷贝的文件来做实验。假定拷贝的文件是test.csv.用下面这个命令

awk '{print}' test.csv | less

大概看下文件,列一下字段名,内容截屏就不放了

Name,CardNo,Descriot,CtfTp,CtfId,Gender,Birthday,Address,Zip,Dirty,District1,District2,District3,District4,District5,District6,FirstNm,LastNm,Duty,Mobile,Tel,Fax,EMail,Nation,Taste,Education,Company,CTel,CAddress,CZip,Family,Version,id

将文件中的字段分割符用制表符代替,生成tmp.csv文件

sed 's/,/\t_/g' test.csv > tmp.csv

通过awk得到我们需要的字段,存到dealed.csv文件中

awk '{print $1,$5,$6,$7,$8,$32}' > dealed.csv

好的,现在有了处理好的文件dealed.csv,那么我们来把玩一番

先来看下男女比例

 awk '$3 ~ /_M/' dealed.csv | wc && awk '$3 ~ /_F/' dealed.csv | wc

输出

31179  187081 2792791
16085   96513 1455873

我们看到,是31179:16085,没有性别的忽略了,仅最小的这个文件来看,男比女大概是2:1的样子,额,说明了什么问题?看官自己发挥想象力吧

再来看看年份情况

awk '$4 ~ /^(_196)/' dealed.csv | wc && awk '$4 ~ /^(_197)/' dealed.csv | wc && awk '$4 ~ /^(_198)/' dealed.csv | wc && awk '$4 ~ /^(_199)/' dealed.csv | wc

输出

4885   29310  447630
9706   58239  884200
20533  123201 1831734
8100   48601  784771

明显看出80后占据开房主力地位!

再来看各年龄层女性占比

awk '$4 ~ /^(_196)/ && $3 ~ /_F/' dealed.csv | wc && awk '$4 ~ /^(_197)/ && $3 ~ /_F/' dealed.csv | wc && awk '$4 ~ /^(_198)/ && $3 ~ /_F/' dealed.csv | wc && awk '$4 ~ /^(_199)/ && $3 ~ /_F/' dealed.csv | wc

输出

   1359    8154  122638
   2922   17533  259771
   7124   42746  634798
   3736   22416  360216

擦,90后女生比例明显高了。

ok,这边先这样。

 

来看看awk 带有-f选项的用法,又能对开放记录做什么手术呢?

引入文件ald

{
if ($4 ~ /^(_199)/ && $3 ~ /_F/) $1 = "阿拉丁和"$1"开房了,今天是"$6
if ($1 ~ /阿拉丁/) print
}

然后awk -f之

awk -f ald dealed.csv | less

xx

我靠,楼主一下子和n个90后妹纸开房了,开个玩笑~

楼主表示,不会泄漏任何信息,也别向楼主提出任何查询请求,本文仅用于技术探讨,over。

 

CodeIgniter保留字

控制器

  • Controller
  • CI_Base
  • _ci_initialize
  • Default
  • index

函数

  • is_really_writable()
  • load_class()
  • get_config()
  • config_item()
  • show_error()
  • show_404()
  • log_message()
  • _exception_handler()
  • get_instance()

变量

  • $config
  • $mimes
  • $lang

常量

  • ENVIRONMENT
  • EXT
  • FCPATH
  • SELF
  • BASEPATH
  • APPPATH
  • CI_VERSION
  • FILE_READ_MODE
  • FILE_WRITE_MODE
  • DIR_READ_MODE
  • DIR_WRITE_MODE
  • FOPEN_READ
  • FOPEN_READ_WRITE
  • FOPEN_WRITE_CREATE_DESTRUCTIVE
  • FOPEN_READ_WRITE_CREATE_DESTRUCTIVE
  • FOPEN_WRITE_CREATE
  • FOPEN_READ_WRITE_CREATE
  • FOPEN_WRITE_CREATE_STRICT
  • FOPEN_READ_WRITE_CREATE_STRICT