【问题标题】:Script/Filter Multi-line & Multi-field records, with variable number of lines脚本/过滤多行和多字段记录,行数可变
【发布时间】:2014-08-07 08:05:32
【问题描述】:

tldr; SAN CLI 命令发出可怕的格式,使自动化变得困难。 这种格式是固定的。

我的问题: 我正在尝试编写已调度的 SAN 快照的联机和脱机脚本, 但是 SAN CLI 将文本包装在不方便的地方。

解决方案所需的输出(每条记录)是两个字段, 快照和状态,在一行中:

VolumeName-YYYY-MM-DD-HH:MM:SS.NNNN.N online/offline
VolumeName-YYYY-MM-DD-HH:MM:SS.NNNN.N online/offline

注意: VolumeName 可以有 1 到 64 个字符,这会导致 有 2-4 行的记录 日程表也可以命名,最多有 64 个字符 这将导致记录为 8 行。

示例。

1. Real world
SAN-01> volume select hv01-200G show snapshots
Name                        Permission Status      Schedule Connections
--------------------------- ---------- ----------- -------- -----------
hv01-200G-2013-11-29-12:33: read-write offline              0
  54.1798.1
hv01-200G-2014-08-05-11:00: read-write offline     Site01 H 0
  00.9698.1                                          V Hour
                                                     ly

2. Longest possible volume name
SAN-01> volume select 123456789012345678901234567890123456789012345678901234
567890123 show snapshots
Name                        Permission Status      Schedule Connections
--------------------------- ---------- ----------- -------- -----------
123456789012345678901234567 read-write offline              0
  8901234567890123456789012
  34567890123-2014-08-07-13
  :05:09.9761.1
123456789012345678901234567 read-write online               0
  8901234567890123456789012
  34567890123-2014-08-07-13
  :05:23.9762.1


3. Shortest volume name
SAN-01> volume select X show snapshots
Name                        Permission Status      Schedule Connections
--------------------------- ---------- ----------- -------- -----------
X-2014-08-07-13:10:35.9764. read-write offline              0
  1
X-2014-08-07-13:10:46.9765. read-write online               0

1

任何人都可以提供一个明智的解决方案 - grep sed awk perl 或 还有什么我可以在 linux 机器上运行的吗?

干杯, 杰森

【问题讨论】:

    标签: awk multiple-columns


    【解决方案1】:

    这个 awk 可以解决问题:

    awk '/(on|off)line/ { o[++c]=$3 } substr($0,0,27)~$1 { v[c]=v[c] $1 } END{ for(i=1;i<=c;++i) print v[i],o[i] }' file
    

    说明

    当单词 on/offline 匹配时,递增计数器c,然后创建并将状态保存到数组o。只要第一列中有内容(即该行的第一个字段与该行的前 27 个字符匹配),就添加到卷数据信息中。处理完文件后,打印出两个数组的对应项。

    测试一下

    真实的:

    $ awk '/(on|off)line/ { o[++c]=$3 } substr($0,0,27)~$1 { v[c]=v[c] $1 } END{ for(i=1;i<=c;++i) print v[i],o[i] }' real    
    hv01-200G-2013-11-29-12:33:54.1798.1 offline
    hv01-200G-2014-08-05-11:00:00.9698.1 offline
    

    最长:

    $ awk '/(on|off)line/ { o[++c]=$3 } substr($0,0,27)~$1 { v[c]=v[c] $1 } END{ for(i=1;i<=c;++i) print v[i],o[i] }' longest 
    123456789012345678901234567890123456789012345678901234567890123-2014-08-07-13:05:09.9761.1 offline
    123456789012345678901234567890123456789012345678901234567890123-2014-08-07-13:05:23.9762.1 online
    

    最短的:

    $ awk '/(on|off)line/ { o[++c]=$3 } substr($0,0,27)~$1 { v[c]=v[c] $1 } END{ for(i=1;i<=c;++i) print v[i],o[i] }' shortest 
    X-2014-08-07-13:10:35.9764.1 offline
    X-2014-08-07-13:10:46.9765.1 online
    

    顺便说一句,您提到您在使用 mawk 时遇到了一些问题。我相信原因是开头的正则表达式。 mawk 不假设扩展正则表达式,所以你必须做一些调整:

    $ mawk '/\(on\|off\)line/ { o[++c]=$3 } substr($0,0,27)~$1 { v[c]=v[c] $1 } END{ for(i=1;i<=c;++i) print v[i],o[i] }' real
    

    应该可以。请注意,我可能错了,因为我没有 mawk 进行测试,但我确实使用 grep 观察到了这种行为:

    $ grep '(on|off)line' real                             # doesn't work
    $ grep -E '(on|off)line' real                          # works (extended regexp)
    hv01-200G-2013-11-29-12:33: read-write offline              0
    hv01-200G-2014-08-05-11:00: read-write offline     Site01 H 0
    $ grep '\(on\|off\)line' real                          # also works
    hv01-200G-2013-11-29-12:33: read-write offline              0
    hv01-200G-2014-08-05-11:00: read-write offline     Site01 H 0
    

    【讨论】:

    • 嗨,Tom,最初您的 awk 脚本对我产生了不同的结果。经过一番摸索,很明显我的操作系统(Ubuntu 12.04.4 LTS)提供的 awk 实际上是 mawk。安装 gawk 后,您的脚本运行良好。不仅感谢您的解决方案,还感谢您的解释!
    • 很高兴你能成功。我已经添加到我的答案中,我认为它现在也应该适用于 mawk。
    猜你喜欢
    • 2012-06-05
    • 2016-12-14
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    相关资源
    最近更新 更多