我试图在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个路径。 "()"之前的部分可以是文本(别名),也可以是数字。
答案 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} }'
/LUN$/
正则表达式匹配)getline
和隐式连接运算符)prefix
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]
想象一下您的输入数据如下所示:
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 ..
这正是上面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]