使用sed或awk解析多路径输出

时间:2012-08-22 19:40:09

标签: linux bash sed awk

我试图在Linux上解析多路径输出以获取我正在编写的脚本,而且我无法找到正确的SED或AWK语法来获得它我想要的方式。我一直在浏览各种网站和stackoverflow示例而没有太多运气。

我想找到一种方法:

temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN
[size=20G]
2:0:0:4  sde        8:64  [active][ready]
1:0:0:4  sdm        8:192 [active][ready]
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN
[size=5.0G]
2:0:0:3  sdd        8:48  [active][ready]
1:0:0:3  sdl        8:176 [active][ready]

看起来像:

temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN [size=20G] 2:0:0:4  sde        8:64  active][ready]
temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN [size=20G] 1:0:0:4  sdm        8:192 [active][ready]
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN [size=5.0G] 2:0:0:3  sdd        8:48  [active][ready]
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN [size=5.0G] 1:0:0:3  sdl        8:176 [active][ready]

**编辑 好吧,这样做更难,我找到了没有Netapp默认设置的多路径配置。这使得NETAPP,LUN无法保证在线。我开始做的事情:

/sbin/multipath -ll | grep -v "round-robin"| sed 's/\[feat.*//g' | sed ':a; $!N;s/\n\([^\n]*\[size\)/ \1/;ta;P;D'

将大小放在主线上以给我一些匹配的东西:

360a98000572d4d2d5834664e68323436 dm-6 NETAPP,LUN [size=50G]
\_ 1:0:0:0  sda 8:0   [active][ready]
360a98000572d4d2d5834664e68395951 dm-7 NETAPP,LUN [size=275G]
\_ 1:0:0:7  sdb 8:16  [active][ready]

但是,我无法通过以下任何示例来匹配" G [$" (我知道如果有任何terrabyte卷,我需要另外一行T)并给我正确的输出。

感谢下面的每个人的建议 **结束编辑

我知道如何清理间距,所以我会在输出正确之后再这样做。将开始多路径信息的行全部以" LUN"结束。每个LUN线(sdx设备)下的服务器可以有1到8个路径。 "()"之前的部分可以是文本(别名),也可以是数字。

7 个答案:

答案 0 :(得分:2)

一种方式:

script.awk的内容:

$1 ~ /^([[:digit:]]:){3}[[:digit:]]$/ {
    printf "%s %s\n", line, $0; 
    next;
}

##$1 ~ /temp|redo/ {
$0 ~ /LUN$/ {
    getline l;
    line = $0 " " l;
}

假设infile包含问题的内容,请运行以下脚本:

awk -f script.awk infile

使用以下输出:

temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN [size=20G] 2:0:0:4  sde        8:64  [active][ready]                                                                                                                                
temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN [size=20G] 1:0:0:4  sdm        8:192 [active][ready]                                                                                                                                
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN [size=5.0G] 2:0:0:3  sdd        8:48  [active][ready]                                                                                                                               
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN [size=5.0G] 1:0:0:3  sdl        8:176 [active][ready]

答案 1 :(得分:1)

我不知道输入的确切规格,但这个单行可能会对您有所帮助:

awk '{if (/LUN$/){ prefix = $0; getline; prefix = prefix " " $0 } else {print prefix, $0} }'

  1. 检查当前行是否以LUN结尾(通过将其与/LUN$/正则表达式匹配)
  2. 如果匹配,则将当前行与下一行连接(使用getline和隐式连接运算符)
  3. 如果没有匹配项,则会输出当前记录以及prefix
  4. PS:您可能需要额外的行过滤,这不应该很难,只需在if分支中添加另一个else

答案 2 :(得分:1)

这可能适合你(GNU sed):

sed '/LUN$/{N;y/\n/ /;h;d};G;s/^\([^\n]*\)\n\(.*\)/\2 \1/' file

说明:

  • /LUN$/{N;y/\n/ /;h;d}对于以LUN结尾的行,添加换行符,然后将以下行添加到模式空间(PS),用空格替换换行符,将PS存储在保留空间(HS)中然后删除PS并在下一个循环中加注星标。
  • G对于所有其他行(路径行),在PS中附加换行符后跟HS的内容。
  • s/^\([^\n]*\)\n\(.*\)/\2 \1/将第一个换行符中的任何内容与其后的任何内容交换,并用空格替换换行符,即将标题信息附加到路径行。

答案 3 :(得分:0)

使用sed:

sed -n '
  # if this is header append the size line
  /LUN$/{
    N;
    s/\n/ /;
    h       # and remember this
  }; 
  # if not header then append to header
  /LUN \[/!{ 
    G; 
    s/\(.*\)\n\(.*\)/\2 \1/;
    p; #and print
  }' input_file

没有评论:

 sed -n ' /LUN$/{ N; s/\n/ /; h  }; /LUN \[/!{ G; s/\(.*\)\n\(.*\)/\2 \1/; p; }' input_file

答案 4 :(得分:0)

由于多路径的性质,LUN可以有1+路径,而不仅仅是2路径。 所以getline()可能处于一个丑陋的循环中。 这是一个清晰的awk版本。所有你必须考虑的是如何 标记LUN行,SIZE行和PATH行。

awk '/\(.*\)/ {lu=$0} /^\[size/ {size=$0} $2 ~ /sd/ {print lu, size, $0}'

但是multipath -l可以有更复杂的信息,比如政策,参数等等。

答案 5 :(得分:0)

这是与您类似的一类问题的通用解决方案 - 即解析跨越多行的记录集,但行数可能在记录集之间有所不同。

sed '/([0-9a-f]\{33\})/ i \\' input_file | \
  awk '
    BEGIN {RS=""; FS="\n"}
    {for(i=3; i<=NF; i++) {print $1,$2,$i}}
  '

给出

temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN [size=20G] 2:0:0:4  sde        8:64  [active][ready]
temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN [size=20G] 1:0:0:4  sdm        8:192 [active][ready]
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN [size=5.0G] 2:0:0:3  sdd        8:48  [active][ready]
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN [size=5.0G] 1:0:0:3  sdl        8:176 [active][ready]

此解决方案的属性

  • 标识十六进制摘要上的记录
  • 处理1+路径
  • 轻松扩展以在awk中实现furter逻辑,因为每个多路径记录在awk中被视为记录

解释

想象一下您的输入数据如下所示:

temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN
[size=20G]
2:0:0:4  sde        8:64  [active][ready]
1:0:0:4  sdm        8:192 [active][ready]

redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN
[size=5.0G]
2:0:0:3  sdd        8:48  [active][ready]
1:0:0:3  sdl        8:176 [active][ready]

用awk很容易解析。
你只需要告诉awk ..

  1. 每条记录用空行分隔
  2. 每个字段本身应该只是整行
  3. 然后,为了您想要的结果,打印“第一行,第二行,第i行”组合,直到所有行(字段)都用完为止
  4. 这正是上面awk代码正在做的事情:
    BEGIN {RS=""; FS="\n"}行设置记录sep。到一个空白行和字段sep。换行。
    {for(i=3; i<=NF; i++) {print $1,$2,$i}}行完全符合我之前在3 ..

    之前概述的内容

    现在您只需要引入空白行来分隔您的记录
    对于这个任务,我使用sed。我只需要一个锚来发现前面引入空行的线条。在这里,我使用括号中的十六进制摘要。我认为它总是33个字符。

答案 6 :(得分:0)

修改

awk '/\[size=.*G\]/ { array[prev]++ } { prev = $0 } FNR!=NR { if ($0 in array) { line = $0; getline; line = line FS $0; next } else { print line, $0 } }' file.txt{,}

说明:

## file.txt{,}    
## this is bash shorthand for reading the same file twice

## { prev = $0 }
## keep track of the last line

## /\[size=.*G\]/ { array[prev]++ }
## if the 'size' pattern is found, add the previous line to an array
## now we have an array of lines to search for

## FNR!=NR
## perform the following actions on the second file only

## if ($0 in array)
## if the line is one of our lines that we're searching for

## line = $0; getline; line = line FS $0; next
## store the line, get the next line join it up and go onto the next record

## else { print line, $0 }
## otherwise print out the 'line' and subsequent data

结果:

temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN [size=20G] 2:0:0:4  sde        8:64  [active][ready]
temp (360a98000572d4d2d5834566c64536b46) dm-4 NETAPP,LUN [size=20G] 1:0:0:4  sdm        8:192 [active][ready]
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN [size=5.0G] 2:0:0:3  sdd        8:48  [active][ready]
redo (360a98000572d4d2d5834566c646c366c) dm-3 NETAPP,LUN [size=5.0G] 1:0:0:3  sdl        8:176 [active][ready]