状況に応じてファイルを分割する方法は?

状況に応じてファイルを分割する方法は?

lldpneighborsすべてのサーバーのコマンド結果を含むファイルがあります。このデータをインベントリシステムに簡単にインポートできるように、このファイルをサーバーごとに別々のファイルに分割したいと思います。

入力例

=== Output from 00000000-0000-0000-0000-000000000000 (SERVERNAME1):
Interface 'ixgbe0' has 1 LLDP Neighbors: 
Neighbor 1:
    Chassis ID:         MAC Address - 00 01 02 03 04 05 
    Port ID:        Interface Name - TenGigabitEthernet 0/6
    Time To Live:       120 seconds
    System Name:        name-of-switch-01
    End Of LLDPDU:  
Interface 'igb0' has 1 LLDP Neighbors: 
Neighbor 1:
    Chassis ID:         MAC Address - 00 01 02 03 04 05 
    Port ID:        Interface Name - TenGigabitEthernet 0/23
    Time To Live:       120 seconds
    System Name:        name-of-switch-02
    End Of LLDPDU:  
=== Output from 00000000-0000-0000-0000-000000000000 (SERVERNAME2):
Interface 'ixgbe0' has 1 LLDP Neighbors: 
Neighbor 1:
    Chassis ID:         MAC Address - 00 01 02 03 04 05 
    Port ID:        Interface Name - TenGigabitEthernet 0/2
    Time To Live:       120 seconds
    System Name:        name-of-switch-01
    End Of LLDPDU:  
Interface 'igb0' has 1 LLDP Neighbors: 
Neighbor 1:
    Chassis ID:         MAC Address - 00 01 02 03 04 05 
    Port ID:        Interface Name - TenGigabitEthernet 0/19
    Time To Live:       120 seconds
    System Name:        name-of-switch-02
    End Of LLDPDU: 

これはいくつかのバリエーションを除いて、おおよそのすべての結果の外観です(すべて同じ長さではなく、一部はより多くのインターフェイスのために数行長くなります)。一致させる区切り文字列は次のとおりです。

=== Output from [UUID] ([HOSTNAME]):

理想的には各ファイルの名前をホスト名として指定したいと思います(これは便宜のためだけで必須ではありません)。上記の結果は、次のファイルに分割されます。

サーバー名1

=== Output from 00000000-0000-0000-0000-000000000000 (SERVERNAME1):
Interface 'ixgbe0' has 1 LLDP Neighbors: 
Neighbor 1:
    Chassis ID:         MAC Address - 00 01 02 03 04 05 
    Port ID:        Interface Name - TenGigabitEthernet 0/6
    Time To Live:       120 seconds
    System Name:        name-of-switch-01
    End Of LLDPDU:  
Interface 'igb0' has 1 LLDP Neighbors: 
Neighbor 1:
    Chassis ID:         MAC Address - 00 01 02 03 04 05 
    Port ID:        Interface Name - TenGigabitEthernet 0/23
    Time To Live:       120 seconds
    System Name:        name-of-switch-02
    End Of LLDPDU: 

サーバー名2

=== Output from 00000000-0000-0000-0000-000000000000 (SERVERNAME2):
Interface 'ixgbe0' has 1 LLDP Neighbors: 
Neighbor 1:
    Chassis ID:         MAC Address - 00 01 02 03 04 05 
    Port ID:        Interface Name - TenGigabitEthernet 0/2
    Time To Live:       120 seconds
    System Name:        name-of-switch-01
    End Of LLDPDU:  
Interface 'igb0' has 1 LLDP Neighbors: 
Neighbor 1:
    Chassis ID:         MAC Address - 00 01 02 03 04 05 
    Port ID:        Interface Name - TenGigabitEthernet 0/19
    Time To Live:       120 seconds
    System Name:        name-of-switch-02
    End Of LLDPDU: 

私はcsplitこれを達成するために使用しようとしていますが、何らかの理由で正規表現と一致することはできません。私が試したコマンド:

$ csplit jbutryn_us-west-a_neighbors %===.*:% '{20}'
csplit: ===.*:: no match

$ csplit jbutryn_us-west-a_neighbors /===.*:/ '{20}'
552
552
552
csplit: ===.*:: no match

$ csplit jbutryn_us-west-a_neighbors '/===.*:/' '{20}'
552
552
552
csplit: ===.*:: no match

$ csplit -ks -f test jbutryn_us-west-a_neighbors '/===.*:/' '{20}'
csplit: ===.*:: no match

どんな提案がありますか?

答え1

アッ解決策:

awk '/^===/{ fn=substr($NF,2,length($NF)-3) }{ print > fn }' file

各ファイルの名前は次のように指定されます。CPU名( SERVERNAME<number>)

  • /^===/- 次から始まる行に会うとき===

  • fn=substr($NF,2,length($NF)-3)- ファイル名を設定しますfnsubstr($NF,2,length($NF)-3)- 周囲の括弧を無視してホスト名を抽出します($NF- 最後のフィールド)。

  • print > fn- 基本行をファイルとして印刷

答え2

正規表現を過度に指定しないでください。

$ csplit logfile '/^===/'

xx00これにより、パート1とパートxx012が作成されます。

===または次に始まる別の行がある場合いいえ分割したい場合:

$ csplit logfile '/^=== Output from/'

xx別の固定文字列に置き換えるには、次のようにします-p(残念ながら、この文字列は入力データから取得できません)。

関連情報