shell的效率有那么低吗?

sh/bash/dash/ksh/zsh等Shell脚本
wjjleopard
帖子: 27
注册时间: 2007-06-25 2:13

shell的效率有那么低吗?

#1

帖子 wjjleopard » 2011-10-04 2:04

写了一个shell脚本,主要是sed和awk组合,处理一个1W多行的文件
竟然用了5分钟。

是本来shell性能就这样还是可能我写法有问题?

之前一直用java处理文件,想尝试下shell,却遇到这个问题。在这里请教大家下
头像
cuihao
帖子: 4793
注册时间: 2008-07-24 11:33
来自: 郑州
联系:

Re: shell的效率有那么低吗?

#2

帖子 cuihao » 2011-10-04 6:59

看你怎么写的了。不过,shell效率是不会有太高。
总之,我觉得尽量用一个命令干更多的事。不要弄个循环,调用几千次相同的命令,那样会很慢。

试试perl、python之类的脚本语言吧。
求人不如求它仨: 天蓝的Wiki 屎黄的Wiki 绿
Site: CUIHAO.TK    Twitter: @cuihaoleo
Machine: Athlon64 X2 5200+ / 2x2GB DDR2-800 / GeForce GTS 450
AD: ~まだ見ぬ誰かの笑顔のために~
头像
ChenFengyuan
帖子: 770
注册时间: 2008-03-23 0:39

Re: shell的效率有那么低吗?

#3

帖子 ChenFengyuan » 2011-10-04 20:51

1.awk作为一们语言,完全可以不用shell来调用吧.
2.贴出你的方法.我们来看看有没有地方可以优化
3.shell里面调用sed和awk,我觉得只在一些情况下比较好.一般来说,你调用perl就行了.
4.一般来说调用perl几次来处理.还不如直接用perl写.
5.如果觉得效率低,那就C或者common lisp好了.
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: shell的效率有那么低吗?

#4

帖子 fnan » 2011-10-04 21:04

算法问题,同一个问题,不同算法会有上百倍的效率差别。
或者把问题贴上来,大家试试把时间减到十秒之内。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: shell的效率有那么低吗?

#5

帖子 tusooa » 2011-10-05 16:24

主要是sed和awk组合
尽量只用其中一个

代码: 全选

] ls -ld //
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: shell的效率有那么低吗?

#6

帖子 lilydjwg » 2011-10-06 15:44

wjjleopard 写了:写了一个shell脚本,主要是sed和awk组合,处理一个1W多行的文件
竟然用了5分钟

是本来shell性能就这样还是可能我写法有问题?

之前一直用java处理文件,想尝试下shell,却遇到这个问题。在这里请教大家下
天哪,你这样不如用 vim 呢。。。。
wjjleopard
帖子: 27
注册时间: 2007-06-25 2:13

Re: shell的效率有那么低吗?

#7

帖子 wjjleopard » 2011-10-09 9:15

cuihao 写了:看你怎么写的了。不过,shell效率是不会有太高。
总之,我觉得尽量用一个命令干更多的事。不要弄个循环,调用几千次相同的命令,那样会很慢。

试试perl、python之类的脚本语言吧。
python以后有时间会试试的,刚开始觉得shell和linux联系比较紧,所以尝试了下这个
wjjleopard
帖子: 27
注册时间: 2007-06-25 2:13

Re: shell的效率有那么低吗?

#8

帖子 wjjleopard » 2011-10-09 9:19

ChenFengyuan 写了:1.awk作为一们语言,完全可以不用shell来调用吧.
2.贴出你的方法.我们来看看有没有地方可以优化
3.shell里面调用sed和awk,我觉得只在一些情况下比较好.一般来说,你调用perl就行了.
4.一般来说调用perl几次来处理.还不如直接用perl写.
5.如果觉得效率低,那就C或者common lisp好了.
awk是一门语言?我一直把它当一个命令来看待的……
我只会java,c,perl什么的都没写过,学校的时候写过python的demo,不过很快都扔下了
wjjleopard
帖子: 27
注册时间: 2007-06-25 2:13

Re: shell的效率有那么低吗?

#9

帖子 wjjleopard » 2011-10-09 9:22

ChenFengyuan 写了:1.awk作为一们语言,完全可以不用shell来调用吧.
2.贴出你的方法.我们来看看有没有地方可以优化
3.shell里面调用sed和awk,我觉得只在一些情况下比较好.一般来说,你调用perl就行了.
4.一般来说调用perl几次来处理.还不如直接用perl写.
5.如果觉得效率低,那就C或者common lisp好了.
附件是我写的脚本
附件
al-spliter.sh.zip
access log spliter
(1.2 KiB) 已下载 41 次
wjjleopard
帖子: 27
注册时间: 2007-06-25 2:13

Re: shell的效率有那么低吗?

#10

帖子 wjjleopard » 2011-10-09 9:24

fnan 写了:算法问题,同一个问题,不同算法会有上百倍的效率差别。
或者把问题贴上来,大家试试把时间减到十秒之内。

贴上来了,一个文件的行数大概在10000左右
wjjleopard
帖子: 27
注册时间: 2007-06-25 2:13

Re: shell的效率有那么低吗?

#11

帖子 wjjleopard » 2011-10-09 9:25

另外,感谢大家的回复,我发完这个帖子就会老家了,今天刚回公司
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: shell的效率有那么低吗?

#12

帖子 lilydjwg » 2011-10-09 12:00

wjjleopard 写了:
fnan 写了:算法问题,同一个问题,不同算法会有上百倍的效率差别。
或者把问题贴上来,大家试试把时间减到十秒之内。

贴上来了,一个文件的行数大概在10000左右
那么多 grep 和 awk,还用临时文件,能不慢吗?
头像
link_01
帖子: 1024
注册时间: 2008-11-05 13:24

Re: shell的效率有那么低吗?

#13

帖子 link_01 » 2011-10-09 12:12

wjjleopard 写了:写了一个shell脚本,主要是sed和awk组合,处理一个1W多行的文件
竟然用了5分钟。

是本来shell性能就这样还是可能我写法有问题?

之前一直用java处理文件,想尝试下shell,却遇到这个问题。在这里请教大家下
[bash]#!/bin/bash
#******************************************************
#
# 本脚本的目的是为了从简版EPG的access log中提取
# 时间,ChannelID,loginName和ip
# 生成一个CSV文件,供方便入库
#
# version 0.1 2011-09-27
# author wjj
#******************************************************

format(){
if [ ! -d "$1" ]; then
echo ""
echo ""
echo "process "$1
echo "beginTime:"`date`
logFilePath=${newFolderName}/`basename $1`
#rename the file
logFilePath=${logFilePath%.*}.csv
echo $logFilePath
#check new log file exist
if [ -e "$logFilePath" ]; then
> $logFilePath
else
touch $logFilePath
fi

tempFileName="temp.temp.temp"
#process each line
rowCount=`grep "/simpleEPG/play.jsp" $1 | wc -l`
echo "row counts:"${rowCount} " " $1

#write lines to new file
grep "/simpleEPG/play.jsp" $1 > $tempFileName

count=1
#while [ $count -le $rowCount ]
for row in `cat $tempFileName`
do
#row=`sed -n ${count}p $tempFileName`
myDate=`echo $row | egrep -o '\[.*\]' | awk '{print $1}' | awk 'BEGIN {FS="["} {print $2}'`
channelID=`echo $row | egrep -o '".*"'| awk '{print $2}' | awk 'BEGIN {FS="?"} {print $2}' | awk 'BEGIN {FS="&"} {print $1}' | awk 'BEGIN {FS="="} {print $2}'`
loginName=`echo $row | egrep -o '".*"'| awk '{print $2}' | awk 'BEGIN {FS="?"} {print $2}' | awk 'BEGIN {FS="&"} {print $2}' | awk 'BEGIN {FS="="} {print $2}'`
ip=`echo $row | egrep -o '".*"'| awk '{print $2}' | awk 'BEGIN {FS="?"} {print $2}' | awk 'BEGIN {FS="&"} {print $3}' | awk 'BEGIN {FS="="} {print $2}'`
#write new line to file
echo ${myDate},${channelID},${loginName},${ip} >> $logFilePath
count=$(($count+1))
done
#movei processed file to old folder
mv $1 $oldFolderName
# echo message
echo "endTime: "`date`
echo $1 "processed!"
else
echo "folder $1 ignored!"
fi
}

#exit on any error
set -e

# for simple,the only parameter is the log folder's path
logPath=$1

# check paramter
if [ -z "$logPath" ]; then
echo "usage: $0 logFolderPath"
exit 1
fi

# check folder existing
if [ ! -d "$logPath" ]; then
echo "$logPath not a valid folder"
exit 1
fi
# format the logPath
logPath=`dirname $1`/`basename $1`

# if necessary,mkdir new folder and backup folder
newFolderName=$logPath"/"`date +%F`"-new"
oldFolderName=$logPath"/"`date +%F`"-old"
#echo $newFolderName $oldFolderName

if [ ! -d "$newFolderName" ]; then
mkdir $newFolderName
fi
if [ ! -d "$oldFolderName" ]; then
mkdir $oldFolderName
fi
# format the log files
for logFile in ${logPath}/*; do
format $logFile;
done
[/bash]
我给你贴出来,grep次数很多不必要的,awk可以匹配正则,sed也可以,awk我也不知道用管道有什么缺点,不过还是写成脚本好点。
笔记
-------------------------------------
http://blog.163.com/wqt_1101
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: shell的效率有那么低吗?

#14

帖子 fnan » 2011-10-09 22:35

数据文件呢?不知道数据结构怎么考虑算法?
不过肯定不需开这么多进程,进程越多越慢。(以前测试从两个各五十万行的文件中找出相同的两行大概要9秒左右)
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
wjjleopard
帖子: 27
注册时间: 2007-06-25 2:13

Re: shell的效率有那么低吗?

#15

帖子 wjjleopard » 2011-10-10 9:08

fnan 写了:数据文件呢?不知道数据结构怎么考虑算法?
不过肯定不需开这么多进程,进程越多越慢。(以前测试从两个各五十万行的文件中找出相同的两行大概要9秒左右)
样例

114.76.129.129 - - [15/Sep/2011:22:52:58 +0800] "GET /simple/img/bg.gif HTTP/1.1" 304 -
114.76.129.129 - - [15/Sep/2011:22:53:00 +0800] "GET /simple/img/bg.gif HTTP/1.1" 200 989
114.76.129.129 - - [15/Sep/2011:22:53:02 +0800] "GET /simple/play.jsp?ChannelID=1&loginName=48390800&ip=114.228.5.230 HTTP/1.1" 200 29082
114.76.129.129 - - [15/Sep/2011:22:53:02 +0800] "GET /simple/play.jsp?ChannelID=1&loginName=56538290&ip=122.66.196.28 HTTP/1.1" 200 29082
114.76.129.129 - - [15/Sep/2011:22:53:04 +0800] "GET /simple/play.jsp?ChannelID=9&loginName=49111797&ip=113.52.4.167 HTTP/1.1" 200 29082
114.76.129.129 - - [15/Sep/2011:22:53:06 +0800] "GET /simple/img/bg.gif HTTP/1.1" 200 989
114.76.129.129 - - [15/Sep/2011:22:53:09 +0800] "GET /simple/play.jsp?ChannelID=1&loginName=65738998&ip=121.36.157.47 HTTP/1.1" 200 29082
114.76.129.129 - - [15/Sep/2011:22:53:09 +0800] "GET /simple/play.jsp?ChannelID=8&loginName=66343666&ip=131.128.129.219 HTTP/1.1" 200 29082
114.76.129.129 - - [15/Sep/2011:22:53:11 +0800] "GET /simple/img/bg.gif HTTP/1.1" 200 989
114.76.129.129 - - [15/Sep/2011:22:53:11 +0800] "GET /simple/img/bg.gif HTTP/1.1" 200 989
114.76.129.129 - - [15/Sep/2011:22:53:13 +0800] "GET /simple/img/bg.gif HTTP/1.1" 200 989
回复