【问题标题】:awk and cat - How to ignore multiple lines?awk 和 cat - 如何忽略多行?
【发布时间】:2011-01-10 01:31:06
【问题描述】:

我需要从 D-Link 路由器中提取 Voip 日志,因此我设置了一个小 Python 脚本,通过 telnet 在该路由器中执行命令。 我的脚本执行“cat /var/log/calls.log”并返回结果,但是...... 它还发送不重要的内容,例如 BusyBox 横幅等... 如何忽略从 1 到 6 和最后 2 的行? 这是我当前的输出:

yaba@foobar:/stuff$ python calls.py


BusyBox v1.00 (2009.04.09-11:17+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.

DVA-G3170i/PT # cat /var/call.log
1         ,1294620563,2  ,+351xxx080806  ,xxx530802      ,1  ,3  ,1
DVA-G3170i/PT # exit

而我只需要:

1         ,1294620563,2  ,+351xxx080806  ,xxx530802      ,1  ,3  ,1

(可以有多行) 这样我就可以将其保存到 CSV,然后再保存到 sql db。

谢谢,对不起,我的英语不好。

【问题讨论】:

  • 我认为 headtail 在这方面比 AWK 好...
  • 如果你能保证头部和尾部的长度总是完全相同,那么......它仍然会启动三个重量级进程并将它们连接在一起。 AWK 是一种专门为此类工作而设计的工具,只要您花 15 分钟时间来学习它,它就会做得很好。

标签: filter sed awk cat


【解决方案1】:

为什么不在 AWK 中使用模式来匹配您想要的文本?

python calls.py | awk '/^[0-9]/{print}/'

AWK 的整个 POINT 是根据模式匹配行并操作/打印这些匹配的行。


已编辑以添加示例运行。

这是基于您上面的示例的垃圾数据文件。

$ cat junk.dat


BusyBox v1.00 (2009.04.09-11:17+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.

DVA-G3170i/PT # cat /var/call.log
1         ,1294620563,2  ,+351xxx080806  ,xxx530802      ,1  ,3  ,1
DVA-G3170i/PT # exit

这里是通过带有过滤器的 AWK 运行它。

$ cat junk.dat | awk '/^[0-9]/ {print}'
1         ,1294620563,2  ,+351xxx080806  ,xxx530802      ,1  ,3  ,1

不需要 SED,不需要计算行数,除了 AWK 什么都不需要。为什么要让事情变得比需要的更复杂?

【讨论】:

  • +1 使用 AWK 的另一个优势:看看所有那些刚刚成熟的字段!以awk -F, '/^[0-9]/ {print $1,$3,$4}' 为例。
  • 确实如此。您可以做的不仅仅是复制行。你可以从中提取你需要的东西,把它格式化,用蝴蝶结包起来,然后微笑着递给它。
  • 感谢您的详细解答。 awk 的问题在于椅子和键盘之间,那就是我 :) 我必须 RTF awk M.
  • awk 的手册值得一读。它不是那么大的语言,但它在其问题领域(即面向行的文本操作)中包含了一些真正的力量。
【解决方案2】:

一通电话sed:

sed -n '1,6d;7,${N;$q;P;D}'

或者对于sed的挑剔版本:

sed -ne '1,6d' -e '7,${N' -e '$q' -e 'P' -e 'D}'

你也可以根据匹配来做:

sed -n '/^[0-9]+/p'

或类似的东西。

但是为什么您的 Python 脚本不读取文件并进行过滤(而不是调用外部实用程序)?

【讨论】:

  • 我认为 AWK 对于像日志文件之类的面向行的工作来说是更好的工具,但是这个——尤其是最后一个匹配的——在没有人们建议的奇怪回转的情况下完成了这项工作。
  • 因为 telnetlib 不让我:|
【解决方案3】:

python 调用.py | sed -e 1,6d -e '$d'


所以这可能行得通。它将过滤掉前 6 个和最后一个,这就是您的示例表明您需要的。如果你真的想破坏最后两行,那么你可以这样做:

python calls.py | sed -e 1,6d -e '$d' | sed -e '$d'

但是等等……你说 awk,所以……

python calls.py | awk '{ if(NR > 7) { print t }; t = $0 }'

【讨论】:

    【解决方案4】:

    这可能对你有用:

    sed '1,6d;$!N;$d;P;D' file
    

    【讨论】:

      【解决方案5】:

      我不确定这是不是最好的方法(也许 D-Link 路由器支持 FTP 或 SSH),但你可以用 awk 来做:

      awk '/cat/, /exit/' | sed -e '1d' -e '$d'
      

      awk 将打印包含“cat”和“exit”的行之间的所有内容,不幸的是包括这两行。这就是剩下的命令的用途,我想不出比这更好的方法......

      【讨论】:

      • 你知道 AWK 中的正则表达式匹配,但你想不出可能匹配你想要的值吗?
      • 我怎么知道所有记录的格式是什么?我实际上认为我的解决方案是这里所有解决方案中最好的......
      • 您仔细查看文件并弄清楚了吗?如果它作为一种格式稍微有用,它就会有规则的模式。如果你看不到这些模式,我不确定编程是你的最佳选择......
      猜你喜欢
      • 2021-06-17
      • 2012-07-01
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 2010-12-02
      • 2018-07-07
      相关资源
      最近更新 更多