存档

文章标签 ‘shell’

Shell字符串分割与随机访问

2017年11月10日 没有评论

    Shell经常做的一项工作就是文本处理,通过组合grep、awk、sed等来实现查找、分割、替换、删除等操作。今天说一下对单行字符串的分割处理方法。先看代码:

_uas="Mozilla/5.0 (Linux; Android 5.1.1; Redmi Note 3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/535.19|Mozilla/5.0 (Linux; Android 4.4.4; 2014813) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/535.19|Linux; Android 6.0.1; SM-G9008W) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/535.19|Mozilla/5.0 (Linux; Android 5.0.2; Redmi Note 2) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/535.19"

#生成随机索引
_rand_index=$(expr $RANDOM % 4) 

#设置新的分隔符
OLD_IFS="$IFS"
IFS="|" 
#将UA字符串分割到_arr数组中
_arr=($_uas) 
IFS="$OLD_IFS"

#通过下标访问数组中的元素。
_ua=${_arr[$_rand_index]}

    _uas包含以竖线|分隔的4个安卓UA,我想要随机取其中的一个UA来用。这涉及到两点需求:生成一个随机索引,将字符串按照指定的分隔符来分隔。

    Shell生成随机数的方法可以如上面代码一样直接取系统环境变量$RANDOM也可以通过date +%s的方法获取当前的秒数,再和数组长度取模来实现。当然通过系统时间的方法获得的随机数有可能并不很随机,特别是在操作间隔很短的情况下。

    单行字符串分割可以通过awk来实现,然后分别打印各列的值。但是通过设置系统IFS的方法看起来更直接,能够直接通过($string_line)将元素保存在新的数组中,这样就可以以下标的方式来访问。

    Shell还是博大精深的,不常用不足以体会其便捷与强大。

分类: Shell, 开发 标签: ,

一个从MongoDB中导出给定日期范围内数据的shell脚本

2017年6月29日 没有评论

前几天介绍了使用mongoexport的使用方法,结合date命令的使用,这里给出一个完整的脚本,用来从MongoDB中导出某个日期范围内的数据,数据导出后从MongoDB中进行删除

#!/bin/sh
#d1, the beginning date, eg:2017-06-28
d1=$1 
d1=`date -d $d1 +%F`
 
#transfer d1 to seconds
d2=`date -d $d1 +%s`
#increase d1 by one day
d2=`expr $d2 + 86400`
#transfer d2 from seconds to day
d2=`date -d @$d2 +%F`

#build query json
qj='{"time":{$gte:ISODate("'"$d1"'T00:00:00Z")}, "time":{$lt:ISODate("'"$d2"'T00:00:00Z")}}'
#export
./mongoexport --db testDB --collection testColl --query="$qj" --fields="userId,userName" --type="csv" --out results"-$d1" --noHeaderLine

#generate js for delete
echo 'var db = connect("testDB");' > delete.js
echo 'db.testColl.remove({"time":{$gte:ISODate("'"$d1"'T00:00:00Z")}, "time":{$lt:ISODate("'"$d2"'T00:00:00Z")}})' >> delete.js
#delete 
./mongo delete.js

备注:如果MongoDB使用的不是默认端口27017,上面的脚本里mongoexport和mongo都需要增加–port参数,并且delete.js中的connect方法也需要指定端口,指定方式为:

var db = connect("127.0.0.1:port/testDB");
分类: MongoDB, Shell 标签: ,

shell中计算偏移日期的方法

2017年6月29日 没有评论

给定一个日期,如何在shell中计算前几天或者后几天的日期?

方法如下:

#给定当前日期
d1=`date +%F`

#计算两天后的日期
offset=2

 #d1转换成秒, since 1970-01-01 00:00:00 UTC
d1s=`date -d $d1 +%s`

#将偏移天数换算成秒数
offset_s=`expr 86400 \* $offset` 

#计算偏移后 的秒数
d2s=`expr $d1s + $offset_s`

#将偏移后的秒数转换成日期
d2=`date -d @$d2s + %F`

主要原理就是通过date -d +%s来实现日期和秒之间的互转,详情man date一下吧。

分类: Shell 标签: ,

wtail:可以多屏输出的多文件跟踪查看工具

2017年5月17日 没有评论

tail是我们常用到的文件跟踪查看工具,-n可以查看末尾n行,-f可以实时跟踪文件(描述符)的最新变化。当然也可以同时查看多个文件,但是多文件的输出是混杂在一起的,没那么直观。

现在好了,我们有了wtail。这是一个可以在同一个终端窗口中同时输出多个被跟踪文件数据的工具,每个文件可以在单独的小屏幕中输出,即一个窗口分屏输出。

  1. 安装
    • wtail依赖libncurses,某些机器上可能没有这个库,需要手动安装:

      wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz

      tar xzvf ncurses-6.0.tar.gz && cd ncurses-6.0

      ./configure && make && make install

    • 下载wtail源码包,解压,make && make install
  2. 使用
    • wtail *.log
分类: Shell, 工具, 运维 标签: , ,

linux下制作二进制 bin文件

2016年3月24日 没有评论

制做方法是使用cat 命令将执行脚本和打包文件同时放到一个.bin的文件里。这样安装的时候只要使用一个包,直接执行该包即可安装完毕,简单方便。
例:制作安装apache、mysql的安装脚本包
1.将源码包先打包
#tar zcvf packages.tar.gz httpd-2.0.63.tar.bz2 mysql-5.0.33.tar.gz

2.编写脚本如下:
# cat install.sh
#!/bin/bash
dir_tmp=/root/installapache
mkdir $dir_tmp
sed -n -e ‘1,/^exit 0$/!p’ $0 > “${dir_tmp}/packages.tar.gz” 2>/dev/null
cd $dir_tmp
tar zxf packages.tar.gz
tar jxf httpd-2.0.63.tar.bz2
cd  httpd-2.0.63
./configure –prefix=/tmp/apache2
make
make install
cd $dir_tmp
tar zxf mysql-5.0.33.tar.gz
cd mysql-5.0.33
./configure –with-charset=gbk –with-extra-charsets=binary,latin1,gb2312 –localstatedir=/home/db –with-mysqld-ldflags=-all-static -enable-assembler –with-innodb –prefix=/tmp/mysql5
make
make install
exit 0

#cat install.sh packages.tar.gz >install.bin

这样就生成install.bin的安装文件,该文件是由shell脚本和二进制合成的。前半部分是脚本后半部分是二进制文件,用strings等二进制查看命令可以看到。
最主要的是下面这句,是将二进制文件从.bin文件里分离出来
sed -n -e ‘1,/^exit 0$/!p’ $0 > “${dir_tmp}/packages.tar.gz” 2>/dev/null

安装的时候直接执行
sh install.bin
安装这个方法可以将我们平时常使用的安装脚本化,然后打包。以后使用就方便了。

 

分类: Shell, 运维 标签: , ,

查找linux大文件

2016年2月18日 没有评论

cd path_to_be_searched;

du -sh *

du可以快速统计指定目录下文件的大小,-s选项可汇总子目录所占的磁盘空间。

Linux的优点就是在于有这么多实用工具,让看似复杂的事情,一条命令就可以解决。

分类: Shell, 监控 标签: ,

一个导出redis有序集合sorted-sets的shell脚本

2015年12月14日 没有评论
  1. 通过keys匹配需要导出的有序集合名称,这些集合命名格式为:*_010_09/Dec/2015
  2. 依次通过zscan导出有序集合中的数据,并分别保存

    #/bin/sh
    zset_pattern=”*_010_09/Dec/2015″
    keys=`redis-cli keys $zset_pattern`
    for k in $keys;do

    _date=`echo “$k”|awk -F”_” ‘{print $3}’|awk -F”/” ‘{print $3″_”$2″_”$1}’`
    out=`echo “$k”|awk -F”_” ‘{print $1″_”$2}’`”_$_date.txt”
    cursor=0

    batches=0
    while [ 1==1 ];do

    reply=`redis-cli zscan $k $cursor`
    cursor=`echo “$reply” | head -n 1`
    pairs=`echo “$reply”|tail -n +2`

    [ $cursor -eq 0 ] && [ $batches -gt 0 ] && break
    batches=`expr $batches + 1`

    skip_key=0
    echo “$pairs”|while read ms

    do

    #skip empty members
    [ “$ms” == “” ] && skip_key=1 && continue
    [ $skip_key -eq 1 ] && skip_key=0 && continue
    if [ “$m” == “” ];then

    m=$ms && continue

    fi
    if [ “$s” == “” ];then

    s=$ms
    echo “$m $s” >> $out
    m=”” && s=””

    fi

    done

    done

    done

分类: Redis, Shell 标签: , ,

使用sendmail发送邮件

2015年11月16日 没有评论

在Linux上发送邮件是经常用到的一个操作,比如自动发告警邮件等。那如何进行配置呢?往下看。

  1. 安装与配置sendmail

    yum install sendmail mail mailx -y
    echo “set from=sender@mail-box smtp=smtp.mail-box” >> /etc/mail.rc
    echo “set smtp-auth-user=sender@mail-box smtp-auth-password=sender-password smtp-auth=login” >> /etc/mail.rc
    service sendmail restart
    chkconfig sendmail on

  2. 发送邮件

    msg=`This is a test mail from sender.”
    echo $msg|/bin/mail -s “Mail title” “recv1@mail-box recv2@mail-box”

  3. 当然你得在mail-box上有个sender账号,并正确设置了密码、pop、smtp等。
分类: 告警, 运维 标签: , ,

c代码中执行shell命令的方法

2015年9月18日 没有评论
  1. 使用system
  2. 使用popen,可以获取shell的输出

FILE * fp = popen(cmd.c_str(), “r”);
if(fp == NULL)
{
cout << “popen failed to excute ” << cmd;
return 1;
}

 

string out;

while(!feof(fp))

{

char buffer[1024] = {0};

fgets(buffer, sizeof(buffer), fp);

out += buffer;

}
pclose(fp);
cout << cmd << “, output is: ” << out;

return 0;

分类: C/C++, 资料 标签: , ,

awk用法总结

2015年8月19日 没有评论

awk是Linux中常用的文本处理程序。现总结常见的用法,持续更新中。

1.查找特定文本并输出行号,比如file的第一列为日期,查找08.19首次出现的位置

awk ‘{ if($1 ~ “19/Aug”) {print FNR;exit} }’ file

2.字段统计

awk ‘{count[$1]++} END {for (i in count) print i, count[i]}’ log

3.通过system调用外部命令,如将学生成绩写入redis数据库的有序集合中以便进行排序等操作

awk -F” ” ‘{system(“redis-cli ” “zincrby ” “StudentScore ” $2 ” ” $1)}’ studentScore.csv

 

分类: Shell, 资料, 运维 标签: , ,