Archive for the ‘scripts’ category

卓越购书单生成命令行

August 17th, 2010

拿到一个小组准备买书的列表,大家把书的卓越的url都放进去了,我决定帮负责订书的同事mm一个忙,不要一个一个点啦,咱们这样,把书的url保存成一个csv文件,比如Book1.csv,然后这么干:

url=http://www.amazon.cn/gp/item-dispatch?submit.addToCart=addToCart; inc=1; sed -ne ‘s/.*\(B0[0-9A-Z]\{8\}\).*/\1/p’ Book1.csv | while read bookid; do url=`echo ${url}\&asin.${inc}\=${bookid}`; inc=$(($inc+1));echo $inc: $url; done;

这样,每行会打出一个url,这个url里的结尾部分就是 &asin.1=B0xxxxxxxx&asin.2=B0xxxxxxxx&asin.3….以此类推,不管有多少本,都可以放到一个URL里,实际测试到75本,没有问题,可以一次性加入。

登录卓越后,打开这个URL就可以一次性添加了。

呵呵,自娱自乐。

一行的日志统计计算脚本

January 20th, 2010

accu=0;sed -ne ‘s/.*bytesIn=\”\([0-9]*\)\”\/>/\1/p’ stage_3.xml |while read num;do cur=$(($num-$accu));accu=$num; echo $(($cur/20/1024/1024));done

记在这里了,先不解释了。

同时操作多台主机的命令行

September 27th, 2009

先让命令行亮相一下:

cat conf/slaves| xargs echo |sed -e "s/ /,/g" | \

sed -e "s/^\(.*\)$/pdsh -f 200 -w \"\1\" \"jps|grep JobShell|cut -f1 -d\’ \’ |xargs kill -9 \"/" | \

/bin/bash

第一行主要就是将一行一个的 slave 整成全在一行里,逗号分隔,第一行的 sed 用 tr 也能干。

第二行的用途是整成一个 pdsh 命令行,这是个同时操作多台机器的工具,pdsh –w 后面是节点列表,也就是刚才那个一行的文件列表。后面用引号引起来一群命令行,这些命令行会送到每台计算机去执行,上面这行实际是去杀掉每个节点上的 JobShell Java 进程。最后,第三行里,是把上面合成的命令行交给 shell 执行

这个命令行看起来长,但实际上并不复杂,这里还有一个变形版本

cat conf/slaves| xargs echo |sed -e ‘s/ /,/g’ | \

sed -e "s/^\(.*\)$/pdsh -f 200 -w \"\1\"
\’ for i in \`seq 2001 2100\`;
do  \/share\/home\/testhdp\/hadoop-0\.19\.2\/bin\/hadoop fs -touchz \`uname -n\`\.\$i ;
done \’ /" | \

/bin/bash

中间一行被断成四行写了,实际不应该断行的,这里面的头一部分和上面是一样的,之后的关键实际是怎么把反引号送出去,而不是当场在本机shell被直接变量替换了,实际处理很简单——将命令行放在单引号里,当然,各种引号和 i 前面的 $ 需要反斜线,否则在送到 bash 之前就被当前 shell 给解释了。这样处理后,反引号会被送到每台机器上,由那台机器上的shell来将反引号打开、变量替换也会在远程进行。

嗯,这个命令行长,但是并不很复杂,有兴趣的朋友可以修改并反馈哈。

一行的日志分析脚本

November 30th, 2008

为了分析hadoop的日志,特地写了个一行的程序,来分析日志程序。Hadoop 是个分布式程序,程序分布在多个节点上,日志自然也是多份的,这里用一行脚本提取所有日志中的关键内容,进行重新排序,方便跟踪,主要是 sed 应用

grep "blk_" hadoop-testhdp-* | sed -ne ‘s/^hadoop-testhdp-\([a-z]\{8\}\)-[a-z]\+-\([0-9]\{1,2\}-[0-9]\{1,2\}\).local.log[^:]*:\(20[0-9]\{2\}-1\?[0-9]-[0-9]\{1,2\} [0-9:,]\{10,12\}\)\(.*\)\(blk_-\?[0-9]\{19\}_[0-9]\{4\}\)\(.*\)$/ \5 \3 [\1] c\2: \4 [The BLK] \6/p’| sort |while read blk remain;do [ "$blk" != "$last" ] && echo "—————-" ; last=$blk ; echo $blk $remain ;done > blocks_log_seg.txt

这个程序主要有两个部分,while之前的是将所有日志放在一起,并提取每行的关键信息,重新排列,然后排序,这样就按照我们关心的方式来排列了,后面一部分(while)是将首个字段发生变化的位置标记出来,以方便查看。sed里面有这么一些关键点:

  • 指定某个表达式的长度:
    • \{8\} 8个长
    • \{10,12\} 10到12个长
    • \+ 至少一个长
    • \? 可能有一个
    • * 多少个都有可能,没有也有可能
  • \( \) 括起来的内容在后面依次可以用  \1, \2, \3…. 的方式来引用
  • 使用 [ ] 来指定可能的字符,或用 [^] 来排除没有的,如 [^:] 就是不包含冒号的,上述[^:]* 如果替换成 .* 的话,可能在 log: 2008-11-28 13:05:33 中做最大匹配,一直到33前面,红色部分的匹配可能是无门不希望看到的。

后面的 while 实际上保存了上一行的 $blk,然后和当前行作比较,如果不同就加如一行减号,从而分隔开不同的行,如果没有需要的话可以去掉,这样会运行得更快些。
注意,该程序的 while 部分在 linux 中运行速度尚可,在 cygwin 中几乎无法接受,如果用 cygwin 的话,建议要么去掉这部分,要么做好等很长时间的准备。

文件路径处理并生成处理命令

October 31st, 2008

这也是个一行命令

find ../hadoop-0.18.1/ \
‘(‘ -name "*.jar" -o -name "*.a" -o -name "*.so*" -o -name "*.gif"  -o -name "*.png" -o -name "*.jpg" -o -name "*.pdf"  ‘)’ \
-exec ‘echo’ ‘{}’ ‘{}’ ‘;’ | \
sed -ne ‘s/\([^ ]*\) \.\.\/hadoop-[\.0-9]*\/\([^\ ]*\)/cp \1 \.\/\2/p’ | \
/bin/sh

这个命令的 find 部分从平级的一个子目录中寻找各种二进制文件,然后把文件路径完整地输出两次,而之后用 sed 把第二遍的目录前缀去掉,换到本目录中的相同位置,再在前面加上 cp 命令,这就构成了一个复制命令。

嗯,这个命令算不算变态要看有多少文件要处理,并且要处理多少次类似操作,如果多的话,费这么点力气写个超长命令行还是值得的。

清理svn仓库的异常状态文件

October 31st, 2008

这个命令行非常初级

svn status|grep ‘!’|awk ‘{print "svn del " $2}’ |/bin/sh
svn status|grep ‘?’|awk ‘{print "svn add " $2}’ |/bin/sh

将有 ! 前缀的文件清除出去,将有 ? 前缀的文件纳入版本管理。

从svn working copy 中删除部分文件

October 31st, 2008

又是一个一句话操作

find . ‘(‘ -name "*.jar" -o -name "*.a" -o -name "*.so*" -o -name "*.gif" -o -name "*.png" -o -name "*.jpg" -o -name "*.pdf"  ‘)’  -exec ‘echo’ ‘svn’ ‘del’ ‘{}’ ‘;’|/bin/sh

这里的要点主要是 find 命令的多条件“或”操作,另外,提供了一种 find 后执行的手段——echo 送至 shell,这样的好处是可以先不添加管道后面的东东,从而观察并验证命令的正确性。这个办法是和 hoplee 老师学的,呵呵。
同理,还可以添加文件

find . ‘(‘ -name "*.jar" -o -name "*.a" -o -name "*.so*"  -o -name "*.gif" -o -name "*.png" -o -name "*.jpg" -o -name "*.pdf"  ‘)’  -exec ‘echo’ ‘svn’ ‘add’ ‘{}’ ‘;’|grep -v ‘\.svn\/’|/bin/sh

只是要注意,放在 .svn/ 中的是 svn 的结构性文件,不能也添加进仓库的。

md5sum 收集并排序

October 25th, 2008

下了一个openclipart 的 daily 发布包,所有文件是按照用户名排序的,文件辨识分类很困难,不管别的了,先选择所有 svg 文件,计算 md5sum,并提取不包含路径的文件名、然后按文件名排序,方便索引。

find . -name "*.svg" -exec ‘md5sum’ ‘{}’ | \
sed -e "s/\([^ ]*\) .*\/\([-a-zA-Z0-9_().]*\.svg\)/\2,\1/g" | \
sort  > md5sums_sorted.csv

md5sum 的输出结果是 md5sum 路径名,这里去掉了前面的路径,只保留文件名,然后把它放在前面,md5sum放在后面,中间用逗号分开,构成csv格式,文件名包括字母、数字、横线、下划线、括号和点。

按路径选择文件

October 22nd, 2008

选取上层目录下的 global 和 util 两个子目录之外的所有子目录的 c 源文件,并送至某程序(这里用 echo 代替)的命令行

ls ../*/*.c | grep -v "^../\(global/\|util/\)" | xargs echo

这里主要是 grep 的或操作需要注意一下,其余没有什么特别的。

用expect进行iLO远程配置

October 16th, 2008

这里是脚本,用途是用 SSH 访问一组指定 ip 的 ilo,执行指定的一组命令,这个例子里是重新设置 IP

#!/usr/bin/expect
set hostfile     [open [lindex $argv 0] ]
set cmdfile     [open [lindex $argv 1] ]
set prompt     ".*iLO->\ "
set passprompt     ".*password:\ "
set rejprompt     ".*refused"
set password    "mypasswd\r"
set timeout    20
set origprefix 192.168.1.
set newprefix 192.168.39.
while {[gets $hostfile h] >0} {
    seek $cmdfile 0
    spawn ssh $origprefix$h
    for {} {1} {} {
        expect {
            "$rejprompt" { puts "refused";break }
            "$passprompt" { send "$password" }
            "$prompt" {
                while { [gets $cmdfile c] > 0 } {
                    send "$c\r" ;
                }
                send "set SubnetMask=255.255.248.0 IPv4Address=$newprefix$h\r"
                expect $prompt
                break
            }
            timeout {puts "timeout"; break}
        }
    }
}
close $hostfile
close $cmdfile

这个脚本接受两个参数,ip尾号列表文件,如下:

85
86
87
88
89
90
91

和 iLO 命令列表文件:

cd map1
cd enetport1
cd lanendpt1
cd ipendpt1

这个脚本有一点特别之处——最后一个操作是设置 IP 地址,设置生效之后 SSH 连接就会自动断开,因此没有 close。

Switch to our mobile site