纯文本数据处理的实用脚本(bash,awk)

计算最大字段长度

典型用途:csv文件导入到数据库时,用于规划字段长度

$ cat file.csv |awk -F "," -v fields_count=10 'BEGIN{for(i=1;i<=fields_count;i++){xcount[i]=0}} {for(i=1;i<=fields_count;i++){if(xcount[i]<length($i) ){xcount[i]=length($i)}}} END{for(i=1;i<=fields_count;i++){print i,xcount[i]}}'

合并将当前目录下所有.csv文件,只保留惟一的首行

典型用途:一系列csv文件,列完全一致,首行是列名;需要将它们合并后做后期处理,通常我们只要保留一个列名行即可。

要求:1) 所有csv文件结尾是空行,否则接合处坏掉;标准的csv文件结尾会有个空行的。 2) 不能有字段内换行符;即字符内换行符需要转义,而不是excel生成的csv文件那样操蛋的转义规则(不转义换行符;用两个并列双引号转义双引号)

head -1 `ls *.csv |grep -v "all.csv" |head -1` >all.csv; total=0;for file in `ls -d *.csv|grep -v 'all.csv'`; do echo -n $file '    '; n=`wc -l $file |awk '{print $1}' `;n=$((n-1));total=$((total+n));echo -n $n 'lines...    ';tail -$n $file >>all.csv;echo ' done'; done; echo 'total lines:    ' $total

实现方法简述:找一个csv文件,将第首行写到all.csv中,然后遍历所有csv文件(除all.csv外),计算行数,将行数减1,将结尾的这么多行追加到all.csv中

cygwin下python环境一些包的踩坑记录

坚持使用cygwin下的python,只有一个原因,要使用cygwin环境下unix/gnu-linux工具;但,毕竟cygwin不是真正的unix/linux,有一些问题貌似无法解决的,钻牛角尖折腾半天,结果还是失败,所以有必要做个踩坑记录,或者也可以说是踩雷记录。

貌似无解的一些包

psutil

[psutil (process and system utilities) is a cross-platform library for retrieving information on running processes and system utilization (CPU, memory, ...] 不支持信息参看,其github上的讨论贴 https://github.com/giampaolo/psutil/issues/82

依赖它的一些包,就不要指望安装了,即使装上运行,结果也有可能异常,如 scipy, matplotlib, scipy, scikit-learn,

不过,因为cygwin本身包含了matplotlib 包,可以使用它安装,如果是venv环境,把安装后的文件从 site-packages 里拷到venv下使用,经验上应该没有什么问题。如果运行中提示缺少依赖包(至少包括 mpl_toolkits)也要同步拷过来 。

 

cygwin:生存指南(简介,安装,使用,技巧)

前言

cygwin是让windows获得unix/linux部分功能的一个神器,本文是个人的一些经验,推荐初学者参考。有一经验的读者也可参阅斧正。

cygwin是什么?

cygwin是运行在windows下的GNU/linux环境,包含了几乎所有的常用Linux软件,使用上跟linux高度一致。由RedHat主导开发。cygwin官网

cygwin安装

到cygwin官网上下载安装程序: setup-x86.exe (32-bit ) or setup-x86_64.exe (64-bit )。双击运行,有安装向导,照做即行。

其中有两个路径一个url,有必要关注一下:

Root Directory, cygwin将安装到这个目录,推荐装到 D:\cygwin  (原因:重装windows通常不影响D盘;目录层级浅,找起来方便)

Local Package Directory, 安装向导下载的安装包存储路径,放到 F:\cygwin_download  或你希望的目录,cygwin安装后其中的文件就可以删除了,不过如果硬盘有空间,留着也不多,毕竟下次添加/更新安装包时,有可能还用得着。另外安装程序 setup-x86.exe 或 setup-x86_64.exe 也推荐放到这个目录里,cygwin里添加/删除包时还要用它(它相当于yum/apt-get,不过是gui版的,不是cli)

Choose A Download Site, 为了更快的下载安装包,推荐选择国内的镜像站点,自行添加镜像url也是可以的,比如下面这几个:

  • http://mirrors.neusoft.edu.cn/
  • http://mirrors.ustc.edu.cn/
  • http://mirrors.aliyun.com/
  • http://mirrors.163.com/

安装后,默认会在桌面放一个图标,可以将该快捷方式复制到你习惯的地方,比如快速启动栏。

默认情况下,cygwin只安装要最小化的环境,需要装哪些软件,使用 setup-x86.exe 或 setup-x86_64.exe安装器另外安装。

cygwin使用

点桌面图标快捷方式,进入cygwin命令行窗口,假装你在linux下,尽情使用吧,因为绝大多数操作都是兼容的。

cygwin文件系统与windows目录之间的对应

  • cygwin的根目录,其实就是cygwin安装目录,按前面的目录就是 D:\cygwin.
  • windows下的盘符,已被挂载到 /cygdrive/c, /cygdrive/d, /cygdrive/x ...

实用技巧

  • cygwin窗口里,鼠标圈选的,就自动复制到windows剪贴板。
  • Shift + Insert,从windows剪贴板粘贴。
  • 双击自动选择连续内容,很方便。
  • 单引号括起来的windows风格的路径。举例快速进入目录 F:\software\tools 可以这样  cd 'F:\software\tools'
  • Ctrl + 鼠标滚轮,调整字体大小。
  • 窗口标题栏点右键 - Option, 还有一系列选项。

一些事实

  • 需要注意的是,cygwin下的软件,都是.exe格式的,原生的linux二进制文件是不能运行的。如果cygwin里没有要用的软件,可以尝试在cygwin下从源码编译。

一些经验

  • cygwin本身是支持x-window的,不过效果实在不怎么样,使用还很烦琐;我想你肯定看不下去、而且用不下去的。所以,不推荐安装图形化的工具了,占磁盘空间而用又没用。如果你使用gitk以图形化查git历史的话,参考 在cygwin里调用windows版git-scm的gitk/git-scm与cygwin协同工作
  • 网上有些文章建议把cygwin目录加入到windows环境变量,不推荐修改,毕竟cygwin与windows的cmd是不同的东西,混用会有些乱,有可能带来莫名其妙的问题。
  • 可以通过 cd c: 进入windows的c盘,甚至可以通过 cd C:\tools 进入子目录;但列强反对这么用,使用windows风格的路径,请一定用单引号括起来。原因 反斜线在bash里当作转义符使用。这样 cd C:\tools 事实上相当于 cd C:tools,这样写cygwin认可。而cd c:\tools\disk相当于cd: c:toolsdisk,自然是错误的。
  • 默认情况下,windows的PATH环境变量,会被追加到cygwin的PATH环境变量中。于是,在cygwin下可以直接调用相关的windows程序。然而,这会造成一些麻烦。比如,安装过windows版ssh客户端,但没有安装cygwin版,在cygwin可以直接使用ssh,但它并不使用 ~/.ssh/下的密钥或匹配文件。这是自然而然的,并且是合理的,可如果不知道“是windows版ssh在工作”的这个事实,这会很令人困惑。

 

 

 

MySQL(csv,text)导入mssql方法参考

分两步处理,第一步是将csv导入到mysql。没有使用mssql自带客户端的导入功能,因为这个功能太坑,尝试N多种方法仍然是报错,因此选择先转换成mysql做中间步骤。

csv/text导入MySQL

一批很大的csv数据(其实并非csv,而是制表符分隔字段),要导入到mssql数据库里。

首先在cygwin下使用awk对数据做预处理,只筛选出字符数正确的行。并且在首行加入列名,以便导入工具自动做列对应。

然后计算各字段最大长度;因为字段数太多(63个),所以计算一下,用于构造create table语句。对于最大长度在255以下的字段使用varchar(n)型,255以上使用longtext类型。

#参考下面语句
$ awk -F "\t" 'NF==63 {print $0}' all.csv >all_63f.txt
$ head -1 origin_text_file.txt >h.txt
$ dos2unix h.txt       #注意最好不要带BOM,否则自行另存一下,避免麻烦
$ cat h.txt all_63f.txt >a63_with_head.txt

#最大计算字符长度,本身并不复杂,只是写在一行里,阅读不太方便
$ awk -F "\t" 'BEGIN{for(i=1;i<=63;i++){xcount[i]=0}} {for(i=1;i<=63;i++){if(xcount[i]<length($i) ){xcount[i]=length($i)}}} END{for(i=1;i<=63;i++){print i,xcount[i]}}' all_63f.txt

接下来使用Navicat for MySQL将导入csv。navcate可以试用,功能足够用;如果使用频繁,建议购买授权。

MySQL导入mssql

以下win2008 x64下的mssql 2012为例。

安装mysql的.net驱动 http://dev.mysql.com/downloads/connector/

create table,建表,与mysql结构一致。

使用mssql自带导入功能导入数据,导入数据源选择 .Net Framework Data Provider for MySQL,填写必要的主机名、登录名、口令,如下

mysql_import_into_mssql_via_nf

不能选择源数据表,必须写select 语句,如: select f1,f2,f3... from `db`.`table` where 1

后面应该没有什么难度了。

phpmyadmin3.x版在windows下的新版本php里日期显示乱码的补丁方案

> 这个问题应该在php5.5.30 与 7.3.11中不再出现。或许,这是灵异问题。 
因为近年一直使用在apache里以fast-cgi模式开以一个php5.3运行phpmyadmin;
前几天偶然发现这个问题并不存在了,或许以前真的只是灵异现象。

现象:

一直使用的phpmyadmin3.5版本(RELEASE-DATE-3.5.0,一个做了配置优化的版本 phpMyAdmin_3.5_path8.net),这个版本比较简洁,更新的pma有些臃肿。然而,在windows下使用php5.5, 及php7.0,都发现日期显示成乱码

phpmyadmin_35_date_string_bad

方案:

文件 libraries/common.lib.php , 行1648行

        $format = __('%B %d, %Y at %I:%M %p');

改成

        $format = '%Y-%m-%d %H:%M:%S';

即可,日期格式显示格式示例 2016-01-27 11:49:07

phpmyadmin_35_date_string_fixed

原因:

PMA_localisedDate函数使用了strftime()函数,该strftime函数第一个参数为日期格式,phpmyadmin源程序使用了带中文的格式字符串;而在windows下的php版本,在做格式化时会转成乱码。经确认linux下没有这个问题,pma是正常的。

更好的方案

$format = __('%B %d, %Y at %I:%M %p');
//patch for win
$fs_ver=explode('.',PHP_VERSION);
if( $fs_ver[0] > 5 or ($fs_ver[0] = 5 && $fs_ver[1] >= 4) ){
    if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'){
        $format = '%Y-%m-%d %H:%M:%S';
    }
}

亦即:github. 这样可以更好的兼容性。

 

mac osx下apache下的坑: you don't have permission to access / on this server

max osx下的apache实在别扭,配置文件被拆得支离破碎(虽然有点拆分还是有道理的),这倒可以慢慢适应。无语的是竟然报403错:

apache you don't have permission to access / on this server. mac

Apache/2.4.16 (Unix) PHP/5.5.29

google后,得知,要在Directory指令里,增加一条 Require all granted,如下示:

<Directory "/Users/jnovack/Sites/">
  Options Indexes MultiViews
  AllowOverride All
  # OSX 10.10 / Apache 2.4
  Require all granted
</Directory>

参考http://stackoverflow.com/questions/25250566/apache-localhost-403-error-with-yosemite

被mac osx坑死了。。。。

一些wordpress插件兼容php7.x后的一些修改

不知算不算手贱,把VPS服务器上的php升级到7.0, 虽然7.x与之前的兼容性是很高的,但移除了一大堆过时用法,而某些老应用仍然在使用。对个人wordpress站点里出现的错误,修正记录如下。全部是插件,wordpress官方程序,是没有问题的。

mysql_escape_string() 函数改为addslashes()

wp-thread-comment插件 wp-content/plugins/wordpress-thread-comment/wp-thread-comment.php  有多处

mysql_* 系列函数在php7里全部移除了,所以建议在所有文件里搜索一下 mysql_query, mysql_escape_, mysql_real_eacape 等函数,如:  grep -r mysql_query /path/to/your/site

split()函数改为explode()

auto-save-image插件 wp-content/plugins/auto-save-image/auto-save-image.php  122行

语法兼容

Configure SMTP插件  wp-content/plugins/configure-smtp/configure-smtp.php  171行,为函数定义添加默认值

public function options_page_description( $localized_heading_text = '' ) {

php下数据库持久连接,及apache模块下“数据库并发连接数超限”的潜在风险

php下的多个数据库引擎都提供持久连接的特性,实现了“连接池”的作用,让数据库连接“复用”,目的是减少php引擎连接数据库的消耗。这有类似fastCGI协议的设计初衷:让后端进程复用,节省启动关闭CGI进程的性能开锁。

数据库持久连接的实现方式

这需要从php的运行模式说起。典型的php运行模式是传统CGI、fastCGI、web模块三种。

其中CGI模式不支持持久连接,因为php每次处理请求,都是由一个独立的进程(操作系统的进程)处理,请求处理完毕,进程就销毁了,相应的数据连接之类的资源当然也已不存在,所以CGI本身是不支持持久连接的。

fastCGI模式下,php进程由进程管理器所管理。(apache下实现实例,参看这里)。不管哪种fastCGI方案,其背后都是一系列长期运行的进程(操作系统下的进程),进程本身可以保持资源,因此,php脚本引擎可以提供应用的接口,允许程序员将数据库连接保持下来,供下次php处理请求,可以直接复用这个连接。

web模块下,类似fastCGI模式。linux下apache默认prefork下,每个httpd进程在同一时刻只响应一个http请求,每个httpd进程可以看做一个fastCGI进程。

多数据库账号的持久连接

假设一web服务器下的所有应用,都是持久连接,并且使用了惟一的数据库连接账号。假设共开了10个fastCGI进程在运行,每个进程都保持了一个持久连接,如果当前处理请求需要连接数据库,直接使用该持久连接即可,不需要新连接数据库。事实上,运行一段时间后,就是这样状态。

假设该web服务器下的应用,共有10个数据库连接账号。每fastCGI进程,从启动开始,每处理一个新的数据库账号相关的请求,就要多保持一个持久连接。因为不同数据库账号的连接,肯定不能复用的。这样,在运行一段时间后,每个fastCGI进程都要维持10个持久连接,分别对应每个数据库账号。

以apache模块模式下运行的httpd进程,可以等同于一个fastCGI进程,上面讨论同样适用。

进程数及连接数讨论,及apache下的潜在风险!

如果web服务器下的的php应用,分别使用了多个数据库账号,而且全部连到同一台数据库服务器。这样,

该数据库的并发连接数 = fastCGI进程数 * 数据库账号数
如果php在apache模块下运行,使用httpd进程数代替fastCGI进程数

通常,fastCGI进程数量是比较有限的,对于一台web服务器,它接受的请求里,大多数请求都是静态的(想像一下,一个页面里,通常只有主html文档是动态,而里面的js,css,图片等等元素都是静态;这里不考虑“静态内容全部移到CDN上”的极端情况)。fastCGI进程数数,通常会远比http并发数小。

在apache模块运行的php下,所有请求都是由httpd进程处理的,每个httpd进程都有可能维护每个数据库用户相关的持久连接,如果数据库用户量较大,这个对mysql服务器并发的连接数影响非常大。通常mysql服务器都会设置一个最大并发数据,超过限制后,就不再受新连接!

php下持久连接的更多信息,参考官方文档 http://php.net/manual/zh/features.persistent-connections.php