Замените только определенные соответствия поиска строки

В дополнение к моему более раннему вопросу: Поиск и замена несколько файлов включая подкаталоги, я хочу внести некоторую корректировку, таким образом, я не делаю недействительным CFML. В основном я стараюсь избегать вложенный <cfoutput></cfoutput>.

Команда:

sed -i -re 's/\<\/form\>/\<input type="hidden" name="_token" value="\<cfoutput\>#STOKEN#\<\/cfoutput\>"\>\<\/form\>/gi' ./math.cfm

Изменения:

</form>

Кому:

<input type="hidden" name="_token" value="<cfoutput>#STOKEN#</cfoutput>"/>
</form>

Как я изменил бы команду так, чтобы я мог достигнуть следующего?

  1. Если </form> содержится в <cfoutput>....</cfoutput>, просто вставьте <input type="hidden" name="_token" value="#STOKEN#"/>

Таким образом

<cfoutput>
    ....
    </form>
    ....
</cfoutput>

должен стать:

<cfoutput>
    ....
    <input type="hidden" name="_token" value="#STOKEN#"/>
    </form>
    ....
</cfoutput>
  1. Однако, если </form> в уже не включают <cfoutput>....</cfoutput> затем вставьте <input type="hidden" name="_token" value="<cfoutput>#STOKEN#</cfoutput>"/>

Таким образом

....
</form>

должен стать:

....
<input type="hidden" name="_token" value="<cfoutput>#STOKEN#</cfoutput>"/>
</form>
1
задан 13 April 2017 в 15:23

1 ответ

Отказ от ответственности: это принимает нет </form> теги, помещенные в ту же строку a <cfoutput> или </cfoutput> тег, поскольку это, кажется, имеет место от примера; если это не так это могло бы неправильно себя вести и замена </form> теги, предшествующие a <cfoutput> тег, следующий та же строка и </form> теги после a </cfoutput> тег, предшествующий на той же строке с неправильной строкой. Таким образом, если Ваш случай использования более сложен, чем, как это на самом деле смотрит от примера (т.е. Вы имеете </form> теги в той же строке <cfoutput> или </cfoutput> теги) Вы - более обеспеченное изучение синтаксического анализатора HTML. Иначе это будет хорошо работать.

Используя awk:

awk '/<cfoutput>/,/<\/cfoutput>/ {sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"#STOKEN#\"/>", $0); print; next} {sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"<cfoutput>#STOKEN#</cfoutput>\"/>", $0); print}' infile

awk сценарий расширен:

/<cfoutput>/,/<\/cfoutput>/ {
    sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"#STOKEN#\"/>", $0);
    print;
    next
}
{
    sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"<cfoutput>#STOKEN#</cfoutput>\"/>", $0);
    print
}
  • /<cfoutput>/,/<\/cfoutput>/: выполняет следующий (составной) оператор, только если текущая запись между записью, содержащей a <cfoutput> строка и запись, содержащая a </cfoutput> строка;
  • sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"#STOKEN#\"/>", $0);: заменяет каждое происшествие </form> в текущей записи с <input type="hidden" name="_token" value="#STOKEN#"/>;
  • print: печатает текущую запись
  • next: пропуски к следующей записи
  • sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"<cfoutput>#STOKEN#</cfoutput>\"/>", $0);: заменяет каждое происшествие </form> в текущей записи с <input type="hidden" name="_token" value="<cfoutput>#STOKEN#</cfoutput>"/>;
  • print: печатает текущую запись
user@debian ~ % cat infile
<html>

<!-- stuff -->

</form>
<cfoutput>
    </form>
</cfoutput>

<!-- stuff -->

</html>
user@debian ~ % awk '/<cfoutput>/,/<\/cfoutput>/ {sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"#STOKEN#\"/>", $0); print; next} {sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"<cfoutput>#STOKEN#</cfoutput>\"/>", $0); print}' infile
<html>

<!-- stuff -->

<input type="hidden" name="_token" value="<cfoutput>#STOKEN#</cfoutput>"/>
<cfoutput>
    <input type="hidden" name="_token" value="#STOKEN#"/>
</cfoutput>

<!-- stuff -->

</html>
0
ответ дан 4 October 2019 в 00:23

Другие вопросы по тегам:

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