시스템 구성을 awk 또는 sed와 비교하기 쉬운 형식으로 변환해 보세요.

시스템 구성을 awk 또는 sed와 비교하기 쉬운 형식으로 변환해 보세요.
  1. exit하위 섹션이 섹션 끝을 표시 하거나 표시하는 up탭으로 선언 되는 이러한 구성 스타일에 대한 용어가 무엇인지 아는 사람이 있습니까?

    config
        system
            security
                tacacs
                    server 1.1.1.1 port 88 
                    profile "default"
                exit
                user "one"
                    profile "admin" "reports"
                    password "E$OITGJ@vf2m92;l3j1"
                    home /home/one
                exit
            logs
                log 1
                    data foo
                    data bar
            exit
    
  2. 동일한 탭 줄(이 경우)에서 섹션 끝 선언을 찾아 제목을 선언하는 데 awk/// sed무엇이든 사용할 수 있는 방법이 있습니까? 그런 다음 해당 섹션의 각 줄 앞에 제목을 삽입하면 다음과 같이 보입니다. (따옴표는 선택할 수 있습니다)?trexit

    config system security tacacs server "1.1.1.1" port "88"
    config system security tacacs profile "default"  
    config system security user "one" profile "admin" "reports"
    config system security user "one" password "E$OITGJ@vf2m92;l3j1"
    config system security user "one" home "/home/one" 
    config system logs log "1" data "foo"
    config system logs log "1" data "bar"
    

가장 큰 문제는 섹션 수와 개별 섹션의 이름이 서로 다른 상자/OS 버전 간에 고정되지 않기 때문에 사용자당 또는 섹션당 서로 다른 설정을 가진 20명의 사용자 또는 50개의 로그를 가질 수 있다는 것입니다. 각 섹션에는 더 많은 섹션이 있습니다. 다른 기본값이나 구성 플래그 이름을 사용합니다.

awkand sed와 같은 것을 사용하여 이 작업을 수행 할 수 있어야 할 것 같지만 /(^.*$)(\t\b.*$)*,(exit)/\1\s\2/이 방법을 사용하면 구성에 한 줄만 입력할 수 있습니다.

답변1

형식이 생각난다mtree구성 형식(참조여기예를 들어).

다음 awk프로그램은 데이터를 언급한 새로운 형식으로 다시 포맷합니다. 각 섹션은 4개의 공백의 배수로 들여쓰기되어 있다고 가정하지만 단일 탭을 사용 하도록 FS변수를 변경할 수 있어야 합니다." {4}""\t"

BEGIN { FS = " {4}" }

$NF == "exit" { next }

NF > nf {
        section[++nf] = $NF
        next
}

function output() {
        $0 = ""
        for (i = 1; i <= nf; ++i)
                $i = section[i]
        print
}

{
        hold = $NF
        hold_nf = NF

        output()

        nf = hold_nf
        section[nf] = hold
}

END { output() }

nf변수는 현재 섹션의 필드 수, 즉 구성 행의 "세그먼트" 수입니다. 이 section배열은 현재 nf필드 수를 보유합니다.

코드의 블록은 다음과 같습니다.

  • BEGIN: 이 블록은 FS입력 필드 구분 기호를 정확히 4개의 공백과 일치하는 확장 정규식으로 초기화합니다.

  • $NF == "exit": 이 블록은 "Exit"라고 표시된 줄을 건너뜁니다. 이것이 필요하지 않다는 것이 밝혀졌습니다(한 섹션은 이전 섹션보다 작은 들여쓰기로 끝납니다).

  • NF > nf: 이 블록은 nf현재 입력 라인의 끝부터 section배열의 마지막 필드까지 데이터를 증가시키고 추가합니다. next이 입력 라인의 추가 처리를 건너뛰기 위해 블록 끝에서 이를 호출합니다 .

  • function output(): 호출시 현재 구간을 출력하는 함수입니다. 다음 두 블록에서 이를 호출합니다.

  • 무조건 블록: 여기에 오면 현재 섹션이 출력되어야 합니다(현재 섹션이 종료되었거나 적어도 더 이상 세분화되지 않았습니다). 우리는 함수를 호출하여 output()이를 수행합니다 . 여전히 해당 입력 행에 데이터를 가져와 저장해야 하고 output()현재 입력 레코드가 재설정( $0)되었으므로 유지하려는 데이터를 에 저장합니다 hold. 우리는 값 NF보다 낮을 수 있는 값에 대해 동일한 작업을 수행합니다 nf.

  • END: 입력이 종료되면 마지막 구성 섹션이 아직 출력되지 않은 상태입니다. 이는 를 호출하여 수행됩니다 output().

질문에 제공된 데이터에 대해 테스트합니다.

$ awk -f script file
config system security tacacs server 1.1.1.1 port 88
config system security tacacs profile "default"
config system security user "one" profile "admin" "reports"
config system security user "one" password "E$OITGJ@vf2m92;l3j1"
config system security user "one" home /home/one
config system logs log 1 data foo
config system logs log 1 data bar

관련 정보