6

我正在尝试为我正在编写的脚本解析 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'

它将 size 放在主线上,给我其他匹配的东西:

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 [$”(我知道如果有任何 TB 卷,我将需要为 T 再添加一行)并给我正确的输出。

感谢以下大家的建议**结束编辑

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

4

7 回答 7

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]
于 2012-08-22T20:04:15.643 回答
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/将任何内容交换到第一个换行符之后的任何内容,并用空格替换换行符,即将标题信息附加到路径行。
于 2012-08-23T05:47:06.380 回答
1

我不知道输入的确切规范,但这个单行可能会帮助你:

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

  1. 它检查当前行是否以 LUN 结尾(通过将其与正则表达式匹配/LUN$/
  2. 如果匹配,它将当前行与下一行连接(使用getline和隐式连接运算符)
  3. 如果没有匹配,则输出当前记录以及prefix

PS:您可能需要额外的线路过滤,这应该不难,只需ifelse分支中添加另一个即可。

于 2012-08-22T20:00:30.727 回答
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 中实现进一步的逻辑,因为每个多路径记录都被视为 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 行”,直到所有行(字段)都用完

这正是上面的 awk 代码正在做的事情:
该行BEGIN {RS=""; FS="\n"}设置记录 sep。到空行和字段 sep。换行。
然后这条线{for(i=3; i<=NF; i++) {print $1,$2,$i}}完全符合我之前在 3.. 下概述的内容。

你现在需要的只是引入空白行来分隔你的记录
对于这个任务我使用 sed。我只需要一个锚来发现之前引入空白行的行。这里我使用括号中的十六进制摘要。我假设它总是 33 个字符长。

于 2012-08-23T11:20:37.350 回答
0

由于多路径的性质,一个 LUN 可以有 1 个以上的路径,而不仅仅是两个。所以 getline() 可能处于一个丑陋的循环中。这是一个清晰的 awk 版本。您需要考虑的只是如何标记 LUN 线、SIZE 线和 PATH 线。

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

但是 multipath -l 可以包含更复杂的信息,例如策略、参数等。

于 2012-08-23T02:58:48.120 回答
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
于 2012-08-22T19:59:03.080 回答
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]
于 2012-08-23T11:33:59.933 回答