200分求条shell

金来 2003-09-15 10:23:19
从文件FILEA中的第N行开始查找含有ERROR或者WARNING的行,直到文件结束。
返回:一个存放这些含有ERROR(error)或者WARNING(warning)的所有行的文件FIELB;
以及FILEA的总行数。
...全文
63 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
金来 2003-09-17
  • 打赏
  • 举报
回复
谢谢wti(wti),不过还是不能实现我想要的功能
我已经决定在C中用POPEN调用SHELL了,也解决了大部分功能
现在还有这1条SHELL有待解决,未敢再麻烦fierygnu(va_list) 等高手,这个项目我的部分就OVER了, 现在结贴了, 我以后也会尽我所能帮助greenhand的,特别感谢 fierygnu(va_list), 请到另一贴领取其余100分.
wti 2003-09-17
  • 打赏
  • 举报
回复
用PERL写了一个.
*name: findErro.pl

*usage:
findErro.pl srcfilename distfilename


#! /usr/bin/perl
$srcFile = $ARGV[0];
$distFile = $ARGV[1];
$counter = 0;

open(SRC, $srcFile) or die "can not open the src file";
open(DIST, ">$distFile") or die "can not open the dist file";
select DIST;
while(<SRC>){
if(/[ERROR|WARNING]/){
print $_;
}
$counter++;
}

print "there are $counter lines in the file\n";
close SRC;
close DIST;
金来 2003-09-17
  • 打赏
  • 举报
回复
我一开始是这么想的:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define shellbuf "awk 'BEGIN {} END { print NR }' "

main()
{
char szbuf[256],filename[20]={"FILEA"};
FILE *p;
sprintf(szbuf,"%s%s",shellbuf,filename);
p=popen(szbuf,"r");
if(!p){

printf("popen error\n");

}
while(fgets(szbuf,sizeof szbuf,p)!=0)fputs(szbuf,stdout);

if(pclose(p)){
printf("pclose error\n");
}
比mmap会不会慢点啊?因为我还要判断文件总是否>=某个行数N.
还有如果我想从最后一行读起就,shell只要tail,而C应该是怎么写啊
fierygnu 2003-09-17
  • 打赏
  • 举报
回复
用mmap把文件map到内存,剩下的就是内存操作了。跳过n个\n到第n+1行,strstr查找子串。总函数当然要数\n了。
fierygnu 2003-09-17
  • 打赏
  • 举报
回复
用mmap把文件map到内存,剩下的就是内存操作了。跳过n个\n到第n+1行,strstr查找子串。总函数当然要数\n了。
金来 2003-09-17
  • 打赏
  • 举报
回复
现在改用C会不会有点紧张啊
而且,我rows记录的是行数,C对文本操作不怎么样啊
如果改用C,还请教怎么从文件FILEB的第rows行开始扫描含有想error,failure关键字的行知道文件结束并记录下文件总行数啊?
fierygnu 2003-09-17
  • 打赏
  • 举报
回复
awk后边是单引号。你的理解有问题,awk里赋值的变量是无法传递回C程序的,只能fgets之后自己解析,用sscanf或者regex、strtok等。可以如下做:
awk '
BEGIN { }
NR > rows {
if ( $0 ~ "failure" )
{ print NR ":" 3 ":" $0> "FILEB"
}
else if ( $0 ~ "error" )
{ print NR ":" 2 ":" $0> "FILEB"
}
else if ( $0 ~ "warning" )
{ print NR ":" 1 ":" $0> "FILEB"
}
}
END { print NR }
' FILEA
这样可以从FILEB里知道是哪行,出了什么错。

你的需求看的很糊涂,我也觉得你用C更好。
fierygnu 2003-09-17
  • 打赏
  • 举报
回复
awk后边是单引号。你的理解有问题,awk里赋值的变量是无法传递回C程序的,只能fgets之后自己解析,用sscanf或者regex、strtok等。可以如下做:
awk '
BEGIN { }
NR > rows {
if ( $0 ~ "failure" )
{ print NR ":" 3 ":" $0> "FILEB"
}
else if ( $0 ~ "error" )
{ print NR ":" 2 ":" $0> "FILEB"
}
else if ( $0 ~ "warning" )
{ print NR ":" 1 ":" $0> "FILEB"
}
}
END { print NR }
' FILEA
这样可以从FILEB里知道是哪行,出了什么错。

你的需求看的很糊涂,我也觉得你用C更好。
passingguy 2003-09-17
  • 打赏
  • 举报
回复
你用C写一个好了,干嘛那么麻烦还要用sripts呢?
不懂~~
金来 2003-09-17
  • 打赏
  • 举报
回复
Begin错了,应该是BEGIN,可是为什么
-bash:BEGIN:command not found
-bash:NR:command not found
我什么没装还是运行的地方错了
PS:我直接在FILEA和FILEB的父目录下运行
金来 2003-09-17
  • 打赏
  • 举报
回复

awk `
Begin
NR > rows {
if ( $0 ~ "failure" )
{ print > "FILEB"
i=3
}
else if ( $0 ~ "error" )
{ print > "FILEB"
i=2
}
else if ( $0 ~ "warning" )
{ print > "FILEB"
i=1
}
}
END { rows=NR }
` FILEA

//在fierygnu(va_list)程序的启事下我写了以上的代码,大家看看这样成吗
//其中rows和i都是我C程序里要用到的变量,把这段程序想如上的方法结合在一起用POPEN调用
金来 2003-09-16
  • 打赏
  • 举报
回复
我先声明一下,我是在C程序中用popen调用由sprintf()函数组合的字符串来执行SHELL的,中间有一些变量,像:
#define COMMAND1 "tail -"
#define COMMAND2 " "
#define COMMAND3 " | sort -n -k 3 | '{ print }END{ print $3 }'"
…………
sprintf(szBuf, "%s%d%s%s%s",COMMAND1,N,COMMAND2,COMMAND3,COMMAND4);
pf=popen(szBuf,"r");
这样来传递我要传变量N到SHELL中的,(估计应该可以这样的吧,不过说的比较罗嗦了点,见晾。:),这只是个例子)。


现在要将执行SHELL以后的某些参数传到程序中,我该怎么办?如下就是我现在的问题:
根据我接收到的lever等级(lever可以是failure或者error)从文件名为FILEA文件中的第rows行查询含有failure,error的错误信息。假设如果有failure,i=3;如果没有,则i=-1;然后传回当前FILEA文件总行数rows。
i和rows正是C程序中需要的值。


谁能给出想这样类似的例子,定给予报酬(分数^^),或者更不知廉耻求这条SHELL,本人来不及学SHELL了
linaxing 2003-09-16
  • 打赏
  • 举报
回复
楼上的这种做法有一个潜在的问题:如果一行中有\t,\c等这样的字符那么它们会被echo转义,从而影响到输出结果的正确性.
为了安全起见,应该使用awk或sed.
fierygnu 2003-09-15
  • 打赏
  • 举报
回复
awk '
BEGIN { N = 10 }
NR > N {
if (($0 ~ "error") || ($0 ~ "warning"))
print > "FILEB"
}
END { print NR }
' FILEA
passingguy 2003-09-15
  • 打赏
  • 举报
回复
#!/bin/sh
##################################
# Already tested in HP-UX 11.0
##################################
#Line counter
line_num=0

#loop the file A
while read line
do
line_num=`expr ${line_num} + 1`

#less then N lines
if [ ${line_num} -le N ]
then
continue
fi

echo ${line_num}:${line}|grep -i "error" >> FILEB
echo ${line_num}:${line}|grep -i "warning" >> FILEB
done < FILEA

#Sum line
echo "Total Lines of FILEA is:${line_num}"

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧