【问题标题】:Filtering the text output in linux过滤linux中的文本输出
【发布时间】:2015-09-08 02:18:58
【问题描述】:

我从 Junos Switches 以这种格式获得输出:

Physical interface: ge-0/0/7, Enabled, Physical link is Up
Queue counters:    Queued packets  Transmitted packets   Dropped packets
  0 N4M-Q1                   0          42210774942              1163342

我只需要一行中的接口名称和丢弃的数据包值,如下所示:

ge-0/0/7 - 1163342

我尝试了sedawk 的许多不同组合。我试图合并 3 行以仅获取我需要的列,但它不起作用。 这就是我尝试合并行的方式:

cat file.txt.out | awk '{getline b; getline c;printf("%s %s %s\n",$0,b,c)}'

但是结果行似乎太长了,所以我无法得到需要的东西。请帮忙

输出看起来像这样(但更长):

Physical interface: ge-0/0/0, Enabled, Physical link is Up
  Queue counters:       Queued packets  Transmitted packets      Dropped packets
    0 N4M-Q1                         0              4582206                    0
Physical interface: ge-0/0/1, Enabled, Physical link is Up
  Queue counters:       Queued packets  Transmitted packets      Dropped packets
    0 N4M-Q1                         0          14419826529               112564
Physical interface: ge-0/0/2, Enabled, Physical link is Up
  Queue counters:       Queued packets  Transmitted packets      Dropped packets
    0 N4M-Q1                         0          67593521901              1675707
Physical interface: ge-0/0/3, Enabled, Physical link is Up
  Queue counters:       Queued packets  Transmitted packets      Dropped packets
    0 N4M-Q1                         0          44283738671               977315
Physical interface: ge-0/0/4, Enabled, Physical link is Up
  Queue counters:       Queued packets  Transmitted packets      Dropped packets
    0 N4M-Q1                         0          98998665742              5065245
Physical interface: ge-0/0/5, Enabled, Physical link is Up
  Queue counters:       Queued packets  Transmitted packets      Dropped packets
    0 N4M-Q1                         0          56932179711              1446413
Physical interface: ge-0/0/6, Enabled, Physical link is Up
  Queue counters:       Queued packets  Transmitted packets      Dropped packets
    0 N4M-Q1                         0          34955222648               578513

【问题讨论】:

  • 使用awk,您可以说awk -F"[ :,]" 'NR==1{print $4} END{print $NF}'。这会在第一行打印第三个文本块,在最后一行打印最后一个文本块。
  • sed 用于单个行的简单替换。就这些。如果您已经在使用 awk,则永远不需要 sed。在您阅读并完全理解 awk.info/?tip/getline 并且对 awk 的其余部分有很好的工作知识之前,不要在 awk 中使用 getline。您永远不需要使用 cat 来打开文件 - 大多数 UNIX 工具自己可以做到这一点(cmd file),其余的 shell 重定向可以做到(cmd < file)。

标签: linux bash text awk sed


【解决方案1】:

仅使用一组样本输入很难猜测,但这可能是您想要的:

$ awk -v RS= '{print $3, $NF}' file
ge-0/0/7, 1163342

如果没有,请发布您的输入文件的几块而不是一个,这样我们就可以更好地了解您要解析的是什么。

鉴于您新发布的示例输入,这就是您所需要的:

$ awk '(NR%3)==1{p=$3} (NR%3)==0{print p, $NF}' file
ge-0/0/0, 0
ge-0/0/1, 112564
ge-0/0/2, 1675707
ge-0/0/3, 977315
ge-0/0/4, 5065245
ge-0/0/5, 1446413
ge-0/0/6, 578513

【讨论】:

  • 我添加了更多输出。您的解决方案看起来很酷,但据我了解,它仅适用于一个输出块。
  • Alex - 不,它适用于多个输入块(records 到 awk),但这些块需要用空行相互分隔。我会看看你现在有什么。好的,我刚刚发布了一个更新的解决方案。
  • 埃德,这很好用。谢谢你。你能解释一下它是如何工作的吗?
  • 当然可以,但你能猜一猜,如果错了我会纠正你?我敢打赌你第一次猜对了。提示:NR 是文件中的当前行号。
  • Ed,抱歉回复晚了。因此,据我了解,前三行使用此部分合并为一个:(NR%3)==1,然后变量 p 采用包含在合并长行的第三行的值。 (NR%3)==0 - 不幸的是,这部分我不清楚。最后是打印p和最后一列的内容。我就是这么看的。
【解决方案2】:

完全脆弱:

$ cat test.txt
Physical interface: ge-0/0/7, Enabled, Physical link is Up
Queue counters:    Queued packets  Transmitted packets   Dropped packets
  0 N4M-Q1                   0          42210774942              1163342

$ echo $(grep -Po "Physical interface: \K[^,]*" test.txt) "-" \
       $(awk '!/Phys/ && !/Drop/ && NF {print $NF}' test.txt)

ge-0/0/7 - 1163342

这样工作:

  • grep -Po "Physical interface: \K[^,]*" test.txt 获取 Physical interface: 之后的所有文本,最多为逗号。
  • awk '!/Phys/ && !/Drop/ && NF {print $NF}' test.txt 在那些不包含PhysDrop 也不为空的行中,打印最后一个字段。

您还可以使用printf 来更好地控制您正在打印的内容:

printf "%s - %s\n" $(grep -Po "Physical interface: \K[^,]*" test.txt) $(awk '!/Phys/ && !/Drop/ && NF {print $NF}' test.txt)

【讨论】:

  • 没问题 :) 注意除了phys/dropp 过滤掉可以插入awk 说awk '!/Phys/ && !/Drop/
  • 哈哈很高兴看到这个!我喜欢你grep -o 的方式。你甚至可以看看后面说grep -Po "Physical interface: \K[^,]*"。这样,通过说 \K 你可以清除上一场比赛,然后打印接下来的比赛。
  • @fedorqui,从一些无用的调用和管道到 grepawkecho 连接在一起。现在看起来好多了,谢谢!
  • 如果您使用 awk,则永远不需要 grep。您的命令可以在一个 awk 命令中以多种方式重写,包括(为了便于与您所拥有的比较)awk '/Physical interface:/{p=$3} !/Phys/ && !/Drop/ && NF {print p, $NF}' test.txt
  • 我建议任何学习 awk 的人阅读 Arnold Robbins 的《Effective Awk Programming, 4th Edition》一书。如果您有任何其他 awk 书籍,请将其扔掉,因为它充其量已经过时了。
【解决方案3】:

好的,经过将近 2 天的挣扎(我是 unix 脚本的初学者),我得到了这个:

 cat myfile | sed -n -e '/Physical/,$p' | egrep -v 'Dropped|master' | awk '{gsub(/Physical interface:|Enabled,|Physical link is|0 N4M-Q1/,"")}1' | sed '/^\s*$/d' | sed -e 's/  \+/ /g' | xargs -n 4 | awk '{ print $1" "$4 }'

产生这样的结果:

ge-0/0/0, 0
ge-0/0/1, 112564
ge-0/0/2, 1675707
ge-0/0/3, 977315
ge-0/0/4, 5065245
ge-0/0/5, 1446413
ge-0/0/6, 578513
ge-0/0/7, 1163342
ge-0/0/8, 1297
ge-0/0/9, 1604987

我意识到这个解决方案可能不是最优化的,但至少它可以满足我的需要;)赞赏“优化”建议:)

【讨论】:

  • 这是完全未优化的:O 我不知道这里最好的是:这是您自己找到的最终解决方案吗?一般来说,如果它一个答案,那么发布你的答案的答案并不是一个坏主意。但如果这是一个额外的问题,您最好编辑您的原始问题并将其发布在那里。此外,最好对你得到的答案提供反馈,并最终接受一个。
猜你喜欢
  • 1970-01-01
  • 2022-11-13
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2017-12-22
  • 1970-01-01
  • 1970-01-01
  • 2015-08-22
相关资源
最近更新 更多