Замените блок многострочного кода в файле, используя bash (sed или awk) - PullRequest
0 голосов
/ 06 апреля 2020

Я хочу заменить большой блок кода из файла в bash, в частности

case $host_os in
     darwin*)
    saved_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS -Wl,-no_weak_imports"
    AC_TRY_LINK([],[],
        [
            LD_MAY_BE_WEAK=no
        ],
        [
            LD_MAY_BE_WEAK=yes
            LDFLAGS="$saved_LDFLAGS"
        ]);;
    *)
    LD_MAY_BE_WEAK=no;;
esac

другие

case $host_os in
esac

присутствуют блоки, поэтому я не могу использовать это как шаблон. Я пытаюсь использовать sed, но мне тяжело с многострочным примером, или я пишу очень длинное регулярное выражение, чтобы точно соответствовать фрагменту, включая табуляцию и пробелы.

     sed -i '.bak' 'case $host_os in\
                darwin*)\
                saved_LDFLAGS="$LDFLAGS"\
                LDFLAGS="$LDFLAGS -Wl,-no_weak_imports"\
                AC_TRY_LINK([],[],\
                [\
                LD_MAY_BE_WEAK=no\
                ],\
                [\
                LD_MAY_BE_WEAK=yes\
                LDFLAGS="$saved_LDFLAGS"\
                ]);;\
                *)\
                LD_MAY_BE_WEAK=no;;\
                esac/d' test_file

this это моя попытка, но я все еще получаю следующие ошибки в зависимости от вариантов.

...": command c expects \ followed by text

или

sed: 1: "/case $host_os in
      ...": unterminated regular expression

Каков наилучший способ сопоставления многострочного выражения?

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

На самом деле это решение, которое я нашел

    sed -i '.bak' ':t
        /case $host_os in/,/esac/ {    
            /esac/!{         
                $!{          
                    N;        
                    bt
                }               
            }               
        /LDFLAGS="$LDFLAGS -Wl,-no_weak_imports"/c\
        case $host_os in \
        \ \darwin19*) \
        \ \AC_MSG_NOTICE([Turning off stack check on macOS 10.15 (Catalina)]) \
        \ \CFLAGS="-fno-stack-check $CFLAGS" \
        \ \;; \
        \ \*) \
        \ \;; \
        esac
        }
        ' erts/configure.in
    fi

, которое было быстро заменено на http://man7.org/linux/man-pages/man1/patch.1.html

0 голосов
/ 06 апреля 2020

Предполагая, когда вы говорите replace, вы имеете в виду remove:

$ cat file
I'm looking to replace a large code block from a file in bash, specifically

case $host_os in
     darwin*)
    saved_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS -Wl,-no_weak_imports"
    AC_TRY_LINK([],[],
        [
            LD_MAY_BE_WEAK=no
        ],
        [
            LD_MAY_BE_WEAK=yes
            LDFLAGS="$saved_LDFLAGS"
        ]);;
    *)
    LD_MAY_BE_WEAK=no;;
esac

other

case $host_os in
esac

.

$ cat badstuff
case $host_os in
     darwin*)
    saved_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS -Wl,-no_weak_imports"
    AC_TRY_LINK([],[],
        [
            LD_MAY_BE_WEAK=no
        ],
        [
            LD_MAY_BE_WEAK=yes
            LDFLAGS="$saved_LDFLAGS"
        ]);;
    *)
    LD_MAY_BE_WEAK=no;;
esac

.

$ cat tst.awk
NR==FNR {
    gsub(/^[[:blank:]]+|[[:blank:]]+$/,"")
    gsub(/[^^[:blank:]]/,"[&]")
    gsub(/\^/,"\\&")
    gsub(/[[:blank:]]+/,"[[:blank:]]+")
    bad = (FNR>1 ? bad ORS : "") "[[:blank:]]*" $0 "[[:blank:]]*"
    next
}
{ rec = (FNR>1 ? rec ORS : "") $0 }
END {
    sub(bad,"",rec)
    print rec
}

.

$ awk -f tst.awk badstuff file
I'm looking to replace a large code block from a file in bash, specifically



other

case $host_os in
esac

Приведенное выше создает регулярное выражение из многострочной строки, которую вы хотите удалить, заменив все пробелы в каждой строке на [[:blank:]]* (и поместите это в начало / конец каждой строки), чтобы пробел не Не имеет значения в соответствии, превращая все другие символы в литералы, чтобы они не обрабатывались как мета-символы регулярного выражения, а затем просто удаляя строку, соответствующую этому регулярному выражению, из содержимого основного файла. Если вы добавите этот оператор в блок END:

print bad | "cat>&2"

, вы увидите на stderr регулярное выражение, которое мы создаем из файла badstuff:

[[:blank:]]*[c][a][s][e][[:blank:]]+[$][h][o][s][t][_][o][s][[:blank:]]+[i][n][[:blank:]]*
[[:blank:]]*[d][a][r][w][i][n][*][)][[:blank:]]*
[[:blank:]]*[s][a][v][e][d][_][L][D][F][L][A][G][S][=]["][$][L][D][F][L][A][G][S]["][[:blank:]]*
[[:blank:]]*[L][D][F][L][A][G][S][=]["][$][L][D][F][L][A][G][S][[:blank:]]+[-][W][l][,][-][n][o][_][w][e][a][k][_][i][m][p][o][r][t][s]["][[:blank:]]*
[[:blank:]]*[A][C][_][T][R][Y][_][L][I][N][K][(][[][]][,][[][]][,][[:blank:]]*
[[:blank:]]*[[][[:blank:]]*
[[:blank:]]*[L][D][_][M][A][Y][_][B][E][_][W][E][A][K][=][n][o][[:blank:]]*
[[:blank:]]*[]][,][[:blank:]]*
[[:blank:]]*[[][[:blank:]]*
[[:blank:]]*[L][D][_][M][A][Y][_][B][E][_][W][E][A][K][=][y][e][s][[:blank:]]*
[[:blank:]]*[L][D][F][L][A][G][S][=]["][$][s][a][v][e][d][_][L][D][F][L][A][G][S]["][[:blank:]]*
[[:blank:]]*[]][)][;][;][[:blank:]]*
[[:blank:]]*[*][)][[:blank:]]*
[[:blank:]]*[L][D][_][M][A][Y][_][B][E][_][W][E][A][K][=][n][o][;][;][[:blank:]]*
[[:blank:]]*[e][s][a][c][[:blank:]]*
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...