Я пытаюсь использовать TextWrangler, чтобы взять кучу текстовых файлов, сопоставить все в некоторых тегах угловых скобок (пока все хорошо) и для каждого совпадения заменить все вхождения определенного символа другим .

Например, я бы хотел взять что-то вроде

xx+xx <f>bar+bar+fo+bar+fe</f> yy+y <f>fee+bar</f> zz

Сопоставить все в пределах <f> и </f>, а затем заменить все + на, скажем, * (но ТОЛЬКО внутри тега "f").

xx+xx <f>bar*bar*fo*bar*fe</f> yy+y <f>fee*bar</f> zz

Я думаю, что могу легко сопоставить теги "f", содержащие +, с таким выражением, как

<f>[^<]*\+[^<]*</f>

Но я понятия не имею, как заменять только подкласс символа для каждого совпадения. Я не знаю априори, сколько плюсов в каждом теге. Я думаю, мне следует запускать регулярное выражение для всех совпадений первого регулярного выражения, но я не совсем уверен, как это сделать.

(Другими словами, я хотел бы сопоставить все +, но только внутри определенных тегов угловых скобок).

Есть у кого-нибудь подсказка?

Большое спасибо, Даниэле

0
danieleghisi 5 Окт 2018 в 02:04

1 ответ

Лучший ответ

Если у вас все в порядке с awk-решением:

$ awk '{
    while ( match($0,/<f>[^<]*\+[^<]*<\/f>/) ) {
        tgt = substr($0,RSTART,RLENGTH)
        gsub(/\+/,"*",tgt)
        $0 = substr($0,1,RSTART-1) tgt substr($0,RSTART+RLENGTH)
    }
    print
}' file
xx+xx <f>bar*bar*fo*bar*fe</f> yy+y <f>fee*bar</f> zz

Вышеупомянутое будет работать с любым awk в любой оболочке на любом компьютере UNIX. Он полагается на отсутствие < в каждом <f>...</f>, как указано в вашем примере кода. Если это возможно, включите это в свой пример, и мы сможем настроить скрипт для его обработки:

$ awk '{
    gsub("</f>",RS)
    while ( match($0,/<f>[^\n]*\+[^\n]*\n/) ) {
        tgt = substr($0,RSTART,RLENGTH)
        gsub(/\+/,"*",tgt)
        $0 = substr($0,1,RSTART-1) tgt substr($0,RSTART+RLENGTH)
    }
    gsub(RS,"</f>")
    print
}' file
xx+xx <f>bar*bar*fo*bar*fe</f> yy+y <f>fee*bar</f> zz
0
Ed Morton 5 Окт 2018 в 02:44