0

我试图弄清楚如何打印两个字符串之间发生的所有内容。问题是,这些字符串对在一行中出现多次。所以我需要能够打印每组对中的每个字段。

我有一个文件api.txt列出了多个客户及其各自的设备清单。它看起来像这样:

Customer [customerId=12000, customerName=Acme, Inc.]
DeviceDetail [baseProductId=router-100, cardDetail=[CardDetail [baseCardId=router-100NIC1, cardDescription=Router 100 NIC, cardSerial=100NIC1], CardDetail [baseCardId=router-100NIC2, cardDescription=Router 100 NIC, cardSerial=100NIC2]], deviceSerial=100PRIMARY, deviceDescription=Router 100 Base Model]
DeviceDetail [baseProductId=router-2500, cardDetail=[CardDetail [baseCardId=router-2500NIC1, cardDescription=Router 2500 NIC, cardSerial=2500NIC1], CardDetail [baseCardId=router-2500NIC2, cardDescription=Router 2500 NIC, cardSerial=2500NIC2]], deviceSerial=2500PRIMARY, deviceDescription=Router 2500 Base Model]
Customer [customerId=24000, customerName=Anvil LLC]
DeviceDetail [baseProductId=router-5000, cardDetail=[CardDetail [baseCardId=router-5000NIC1, cardDescription=Router 5000 NIC, cardSerial=5000NIC1], CardDetail [baseCardId=router-500NIC2, cardDescription=Router 5000 NIC, cardSerial=5000NIC2]], deviceSerial=5000PRIMARY, deviceDescription=Router 5000 Base Model]
DeviceDetail [baseProductId=router-7500, cardDetail=null, deviceSerial=7500PRIMARY, DeviceDescription=Router 7500 Base Model, No NIC]

其输出应类似于:

"12000","Acme, Inc.","router-100","100PRIMARY","Router 100 Base Model","Router 100 NIC","100NIC1","Router 100 NIC","100NIC2"
"12000","Acme, Inc.","router-2500","2500Primary","Router 2500 Base Model","Router 2500 NIC","2500NIC1","Router 2500 NIC","2500NIC2"
"24000","Anvil LLC","router-5000","5000PRIMARY","Router 5000 Base Model,"Router 5000 NIC","5000NIC1","Router 5000 NIC","5000NIC2"

请注意,最后一个 DeviceDetail ( router-7500) 被省略,因为该设备没有附加子设备 ( cardDetail=null)。

我了解如何使用awk将字段分隔符设置为=,捕获它们之间的所有内容(即每个字段值位于等号和逗号之间),但我不确定如何在多个时获得我正在寻找的结果数据的实例CardDetail在每一行上可能出现的次数未知,甚至根本不出现。

需要考虑的是,每个实例都Card Detail被捕获在Card Detail一个封闭的括号 ( ]) 之间,因此这可能有助于捕获每Card Detail行上的每个实例,但不确定。

我也没有结婚awk。使用sed或任何其他解析程序也可以。基本上,任何效果最好的。

提前感谢您提供的任何帮助!

4

1 回答 1

2

当处理变得太尴尬而无法在 awk/sed 中完成时,是时候使用更“现代”的脚本语言了,比如 perl、ruby 或 python。这样的事情应该让你开始(perl):

#!/usr/bin/env perl
use strict;
use warnings;

my $customerName;
my $customerId;
while (my $line = <DATA>) {
    if ($line =~ m{
            customerId=(?<customerId>.*?), 
            \ customerName=(?<customerName>.*)\]
        }x)
    {
            $customerId = $+{customerId};
            $customerName = $+{customerName};
    } elsif ($line =~ m{
                    baseProductId=(?<baseProductId>.*?),
                    \ cardDetail=\[.*baseCardId=(?<baseCardId>.*?),
                    \ cardDescription=(?<cardDescription>.*?),
                    .*deviceSerial=(?<deviceSerial>.*?),
                    \ deviceDescription=(?<deviceDescription>.*)\]
              }x)
    {
            my ($productId, $cardId) = ($1, $2);
            print '"'
            . join('","',
                    $customerId,
                    $customerName,
                    $+{baseProductId},
                    $+{baseCardId},
                    $+{deviceSerial},
                    $+{deviceDescription},
                    $+{cardDescription},
               )
            . "\"\n" ;
    }
}

__DATA__
Customer [customerId=12000, customerName=Acme, Inc.]
DeviceDetail [baseProductId=router-100, cardDetail=[CardDetail [baseCardId=router-100NIC1, cardDescription=Router 100 NIC, cardSerial=100NIC1], CardDetail [baseCardId=router-100NIC2, cardDescription=Router 100 NIC, cardSerial=100NIC2]], deviceSerial=100PRIMARY, deviceDescription=Router 100 Base Model]
DeviceDetail [baseProductId=router-2500, cardDetail=[CardDetail [baseCardId=router-2500NIC1, cardDescription=Router 2500 NIC, cardSerial=2500NIC1], CardDetail [baseCardId=router-2500NIC2, cardDescription=Router 2500 NIC, cardSerial=2500NIC2]], deviceSerial=2500PRIMARY, deviceDescription=Router 2500 Base Model]
Customer [customerId=24000, customerName=Anvil LLC]
DeviceDetail [baseProductId=router-5000, cardDetail=[CardDetail [baseCardId=router-5000NIC1, cardDescription=Router 5000 NIC, cardSerial=5000NIC1], CardDetail [baseCardId=router-500NIC2, cardDescription=Router 5000 NIC, cardSerial=5000NIC2]], deviceSerial=5000PRIMARY, deviceDescription=Router 5000 Base Model]
DeviceDetail [baseProductId=router-7500, cardDetail=null, deviceSerial=7500PRIMARY, DeviceDescription=Router 7500 Base Model, No NIC]

您可以在(搜索修饰符) 中查找x匹配m{}运算符的选项。还可以在同一 perldoc 中搜索捕获组以获取咒语。perldoc perlre/xnamed$+{foo}

于 2013-01-21T14:46:40.227 回答