문제 설명:

문제 설명:

내 경우에는 CMakeLists.txt 전체를 한 번에 편집해야 했지만 문제는 일반화될 수 있다고 생각합니다. 문제는 다음과 같습니다

  1. 작업에 어떤 도구가 더 좋나요?
  2. 원하는 출력을 어떻게 얻을 수 있습니까?

[Optional:]

  1. sed에서 예약된 공간을 지우거나 지우는 방법이 있습니까?
  2. 예약된 공간에 행을 추가하거나 추가하는 방법이 있습니까?

target_include_directories에 대한 두 번의 호출은 동일한 매개변수를 가질 수도 있고 그렇지 않을 수도 있습니다.

문제 설명:

및 범위 내에서 target_include_directories(먼저 )들여쓰기(공백 4개 들여쓰기)가 포함된 모든 줄을 수집 windows하고 앞에 배치합니다 ).

이제 $<$<PLATFORM_ID:Windows>:위에 정의된 범위 내에서 올바른 들여쓰기가 포함 줄 블록 앞에 삽입되고 windows들여쓰기가 포함된 줄이 포함 줄 블록 뒤에 추가됩니다.>windows

또한 각 블록의 매개변수를 포함하는 마지막 줄에는 세미콜론이 없지만 다른 모든 줄에는 세미콜론이 있는지 확인하십시오.

지금까지 수행된 연구:

아래 줄은 창을 포함하는 줄을 모아서 올바른 위치에 배치하지만 들여쓰기나 장식은 없습니다.

sed ':j;/^$/h;/target_include_directories(/,/)/{/windows/{H;d};/)/{H;x;D;G;bj}}' CMakeLists.txt

견본:

...
##############
# Unique Big Block
##############
if(some_condition)
    target_include_directories(foo Public
        arg0floor;
        arg1windowsred;
        arg2chairs;
        arg3bluewindows;
        arg4tables;
        ...
        argnwalls
    )
elseif(some_other_condition)
    target_include_directories(foo Public
        arg0yeast;
        arg1windowsbroken;
        arg2barley;
        arg3wavywindows;
        arg4water;
        ...
        argnsugar
    )
endif()
##############
# Other Unique Big Block
##############
...

예상 출력:

...
##############
# Unique Big Block
##############
if(some_condition)
    target_include_directories(foo Public
        arg0floor;
        arg2chairs;
        arg4tables;
        ...
        argnwalls
        $<$<PLATFORM_ID:Windows>:
            arg1windowsred;
            arg3bluewindows;
            ...
            argkwindowsblack
        >
    )
elseif(some_other_condition)
    target_include_directories(foo Public
        arg0yeast;
        arg2barley;
        arg4water;
        ...
        argnsugar
        $<$<PLATFORM_ID:Windows>:
            arg1windowsbroken;
            arg3wavywindows;
            ...
            argkmilkywindows
        >
    )
endif()
##############
# Other Unique Big Block
##############
...

답변1

  1. 나는 동의한다하카타, AWK 또는 Perl이 더 적합합니다. 여기서는 AWK를 사용하고 있으며 작업을 수행하는 데 충분합니다.

  2. 관련된 단계는 다음과 같습니다. AWK는 기본적으로 레코드 기반 패턴 일치 언어입니다. 레코드는 행입니다. 따라서 이 경우에는 프로그램을 작성하겠습니다.

    1. 를 찾아서 target_include_directories이제 우리가 포함 블록 안에 있음을 확인하세요.
    2. 포함 블록 내부에서는 "창"을 포함하는 행을 일치시키고 이를 출력하는 대신 배열에 저장합니다.
    3. 포함 블록 내부에서 닫는 대괄호를 찾고, 발견되면 플랫폼 접두사와 함께 저장된 줄을 인쇄합니다.

    후행 세미콜론을 처리하려면 몇 가지 추가 처리가 필요합니다. 이를 처리하는 한 가지 방법은 선행 공백과 후행 세미콜론 없이 포함된 줄을 저장하고 상황에 따라 장식하는 것입니다.

    이를 달성하는 한 가지 방법은 다음과 같습니다.

    #!/usr/bin/gawk -f
    
    # Note the start of a block, clear the memorised includes,
    # print the current line and skip to the next one
    /target_include_directories/ {
        in_include_block = 1
        delete includes
        print
        next
    }
    
    # In a block, if we match "windows", memorise the value without its semi-colon
    in_include_block && /windows/ {
        includes[length(includes)] = gensub(";", "", "g", $1)
    }
    
    # In an include block, when we reach the end, output the memorised includes
    in_include_block && /)/ {
        if (length(includes) > 0) {
            printf "        $<$<PLATFORM_ID:Windows>:"
            for (i = 0; i < length(includes); i++) {
                if (i > 0) {
                    printf ";"
                }
                printf "\n            %s", includes[i]
            }
            print "\n        >"
        }
        in_include_block = 0
    }
    
    # In an include block, if we don't match, print the line
    in_include_block && !/windows/
    
    # Outside include blocks, print
    !in_include_block
    

관련 정보