Извлечение данных из вложенных скобок в bash

Установите его в /etc/X11/xdm/Xsetup:

sleep 2 && import -w root /tmp/xdm.jpg &

Скриншот будет сделан через две секунды после запуска xdm и помещен в папку /tmp.

0
15.04.2020, 16:10
3 ответа

На самом деле это идеальное использование для Tcl--того, что данные являются допустимым синтаксисом Tcl, поэтому нам просто нужно определить networkфункцию, и у нас есть допустимый DSL:

#!/usr/bin/env tclsh

proc network {_ name data} {
    set values [lmap val [concat $name [dict values $data]] {
        format {"%s"} [regsub -all {\s+} [string trim $val] " "]
    }]
    puts [join $values,]
}

puts {"Vlan","Description","Interfaces","MTU"}
source [lindex $argv 0]

, затем

$ tclsh parse.tcl datafile
"Vlan","Description","Interfaces","MTU"
"internal-vlan","internal-use","1.1 { } 1.2 { }","1500"
"external-vlan","external-use","2.1 { } 2.2 { }","1500"

Или установите tcllib , чтобы он мог обрабатывать вывод CSV:

#!/usr/bin/env tclsh
package require csv

proc network {_ name data} {
    puts [csv::join [lmap val [concat $name [dict values $data]] {
        regsub -all {\s+} [string trim $val] " "
    }]]
}

puts [csv::join {Vlan Description Interfaces MTU}]
source [lindex $argv 0]
$ tclsh parse.tcl datafile
Vlan,Description,Interfaces,MTU
internal-vlan,internal-use,1.1 { } 1.2 { },1500
external-vlan,external-use,2.1 { } 2.2 { },1500

Для более старой версии Tcl 8.5 добавьте этот процесс в начало программы:

proc lmap {varname list body} {
    upvar 1 $varname element
    set result {}
    foreach element $list {
        lappend result [uplevel 1 $body]
    }
    return $result
}

Для обработки различных типов сетей, а также значения «none», а также для обеспечения правильного порядка полей:

proc network {type name data} {
    if {$type ne "vlan"} {
        return
    }
    set values [list $name]
    foreach key {description interfaces MTU} {
        set val [expr {[dict exists $data $key] ? [dict get $data $key] : "none"}]
        lappend values [regsub -all {\s+} [string trim $val] " "]
    }
    puts [join $values,]
}
2
19.03.2021, 02:29

Если ваши входные данные одинаковы, вы можете попробовать что-то вроде следующего:

#! /usr/bin/perl
use strict;
use warnings;
use feature qw{ say };

say 'Vlan,Description,Interfaces,MTU';
my @interfaces;
while (<>) {
    if (/(?|network vlan (.*) \{|description (".*"))/) {
        print "$1,";
    } elsif (/interfaces/) {
        @interfaces = ();
    } elsif (/ *(.* \{ \})/) {
        push @interfaces, "$1";
    } elsif (/MTU \{/) {
        my $next = <>;
        say "@interfaces,$1" if $next =~ /^ *(.*)/;
    }
}

Если разрешены дополнительные вариации данных (, т. е. символы новой строки необязательны ), вам придется написать настоящий синтаксический анализатор.

1
19.03.2021, 02:29

При условии, что формат файла конфигурации одинаков для всех конфигов:
Используя awk:

$ awk '
BEGIN { printf "Vlan,descripton,interfaces,MTU\n" }
{
if ($1 ~ /^network/ ) { printf $3","; }
if ( $1 ~ /description/ ) { printf $2","; }
if ( $1 ~ /^[0-9]\.[0-9]/ ) { printf $1$2$3" "; }
if ( $1 ~ /^[0-9]{2,}/ ) { printf ","$1"\n"; }
} ' input.conf
Vlan,descripton,interfaces,MTU
internal-vlan,"internal-use",1.1{} 1.2{},1500
external-vlan,"external-use",2.1{} 2.2{},1500
0
19.03.2021, 02:29

Теги

Похожие вопросы