LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3048|回复: 32

这样的shell怎么写?[已解决]

[复制链接]
发表于 2004-3-24 03:17:04 | 显示全部楼层 |阅读模式
datafile:
------------------------------------------------
'abc' 'abc' 'sss' -a '/usr/bin/aaa' -t '005' -s '030' ----first1
'abc' 'abc' 'sss' -a '/usr/bin/bbb' +d -t '005' -s '010' ----first2
'abc' 'abc' 'sss' -a '/usr/bin/ccc' +d -h -t '005' -s '111' ----first3
'abc' 'abc' 'sss' -a '/usr/sbin/ddd' -t '5' -s\ ----first4
'abc' 'abc' 'sss' -a '/usr/bin/aaa' +C +d -t '005' -s '090' ----first5
'abc' 'abc' 'sss' -a '/usr/bin/ccc' -t '5' -s '111' ----first6
'abc' 'abc' 'sss' -a '/usr/bin/eee' +d -t '005' -s\ ----first7
'abc' 'abc' 'sss' -a '/usr/bin/ddd http /root/httplog.html' -t '010' -s '010' ----first8
'abc' 'abc' 'sss' -a '/usr/bin/ddd sshd /root/sshdlog.html' -t '005' -s '010' ----first9
---------------------------------------------------
共有5000条记录, 就不多写了. 特点是: 每行都不太一样, 无法用一个标准的分割符分隔. 空格和tab都不行; 有" ' "单引号, 需要去除; 有的项有单引号包括, 有的项没有. 但是前三项是一样的, 都是'abc' 'abc' 'sss'. 需要读取的结果是 sss /xxx ----firstxx. 也就是第三项, -a 后的一项 (也就是程序名), 和最后一项. 比如:
sss /usr/bin/aaa ---first1
sss /usr/bin/bbb ----first2
...
试了好久也没有一个比较好的方法:confused:, 请叫如何写才能输出这样的结果. 最好就是shell cmd. 简短的shell script 也行.

非常感谢!
 楼主| 发表于 2004-3-24 04:01:07 | 显示全部楼层
我又找到了不少 -a 是不在第四项的行. 如:
'abc' 'abc' 'sss' -p '192.168.0.1' -a '/usr/bin/qqq' .....
'abc' 'abc' 'sss' -p '10.10.100.1 255.255.254.1' -a '/usr/bin/zzz' .....
看来表示 -a 后的那项还不能用简单的print $5. 真是烦啊.
发表于 2004-3-24 10:49:14 | 显示全部楼层
给出一个Perl的实例,保存起来"chmod +x prog"后,像shell脚本一样运行即可(./prog)。

  1. #! /usr/bin/perl -w

  2. open OBJFILE, "datafile"
  3.     or die "Error!!!($!).";
  4. while (<OBJFILE>){
  5.     foreach (split){
  6.         if (/(\bsss\b)/){
  7.             print "$1 ";
  8.         }
  9.         if (m{(/.*\b)}){
  10.             print "$1 ";
  11.         }
  12.         if (m{----\w+}){
  13.             print "$_\n";
  14.         }
  15.     }
  16. }
复制代码
 楼主| 发表于 2004-3-24 11:45:23 | 显示全部楼层
非常感谢home_king!perl确实强大! 但是我对perl不熟(想学来着),所以只能看个大概。如果能有shell的方法,就是最好了。还有一个主要原因其实是这段code只是我的一个shell程序的一小段,出来的数据将被其他方法调用。复杂点我也能写,但是想写的精练短小点,所以才贴出来寻求优良的方法。
发表于 2004-3-24 11:52:14 | 显示全部楼层
sss /usr/bin/aaa ---first1
结果要这样的?
发表于 2004-3-24 11:56:16 | 显示全部楼层
最初由 javalee 发表
sss /usr/bin/aaa ---first1
结果要这样的?

[root@home root]# ./prog
sss /usr/bin/aaa ----first1
sss /usr/bin/bbb ----first2
sss /usr/bin/ccc ----first3
sss /usr/sbin/ddd ----first4
sss /usr/bin/aaa ----first5
sss /usr/bin/ccc ----first6
sss /usr/bin/eee ----first7
sss /usr/bin/ddd /root/httplog.html ----first8
sss /usr/bin/ddd /root/sshdlog.html ----first9
发表于 2004-3-24 12:00:52 | 显示全部楼层
最初由 yongjian 发表
非常感谢home_king!perl确实强大! 但是我对perl不熟(想学来着),所以只能看个大概。如果能有shell的方法,就是最好了。还有一个主要原因其实是这段code只是我的一个shell程序的一小段,出来的数据将被其他方法调用。复杂点我也能写,但是想写的精练短小点,所以才贴出来寻求优良的方法。

在shell里用IFS来分割域的,针对具有不规则"分割子"的行,Perl的split能胜任(因为它的分割子正是"\s+"),且代码精炼; 用shell则不然,即使awk也无能为力,最好自己写一个类似split的shell函数吧(shell语法我忘了大半,现在只能用Perl来帮你了,呵呵)。
发表于 2004-3-24 12:10:28 | 显示全部楼层
试试看吧
  1. /home/javalee:cat p
  2. cat datafile|tr -d "'"|awk '{print $3,$5,$7,$NF}'|\
  3. awk '{if($3!~/\//)print $1,$2,$NF;else print $0}'
复制代码
结果:
sss /usr/bin/aaa ----first1
sss /usr/bin/bbb ----first2
sss /usr/bin/ccc ----first3
sss /usr/sbin/ddd ----first4
sss /usr/bin/aaa ----first5
sss /usr/bin/ccc ----first6
sss /usr/bin/eee ----first7
sss /usr/bin/ddd /root/httplog.html ----first8
sss /usr/bin/ddd /root/sshdlog.html ----first9
发表于 2004-3-24 12:20:54 | 显示全部楼层
先去除' 再乾脆找 /usr/bin 和 ---- , 在輸出時自己加上sss 便可以了
发表于 2004-3-24 12:25:23 | 显示全部楼层
要取得最后一个域用 rev 反过来再用 awk '{print $1}'|rev也是可以的。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表