Substituir apenas algumas correspondências de uma pesquisa de cadeia

1

Além da minha pergunta anterior: Procure e substitua vários arquivos, incluindo subdiretórios desejo fazer alguns ajustes para não invalidar o CFML. Basicamente eu estou tentando evitar aninhado <cfoutput></cfoutput> .

O comando:

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

Mudanças:

</form>

Para:

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

Como eu mudaria o comando para que eu conseguisse o seguinte?

  1. Se o </form> estiver contido em <cfoutput>....</cfoutput> , basta inserir <input type="hidden" name="_token" value="#STOKEN#"/>

Assim

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

deve se tornar:

<cfoutput>
    ....
    <input type="hidden" name="_token" value="#STOKEN#"/>
    </form>
    ....
</cfoutput>
  1. No entanto, se o </form> ainda não estiver entre <cfoutput>....</cfoutput> , insira <input type="hidden" name="_token" value="<cfoutput>#STOKEN#</cfoutput>"/>

Assim

....
</form>

deve se tornar:

....
<input type="hidden" name="_token" value="<cfoutput>#STOKEN#</cfoutput>"/>
</form>
    
por PeterKA 16.07.2015 / 22:53

1 resposta

0

Aviso de isenção de responsabilidade : isso pressupõe que nenhuma tag </form> seja colocada na mesma linha de uma tag <cfoutput> ou </cfoutput> , como parece ser o caso do exemplo. se esse não for o caso, isso pode se comportar mal e substituir as tags </form> que precedem uma tag <cfoutput> na mesma linha e tags </form> seguindo uma tag </cfoutput> anterior na mesma linha com a string errada. Portanto, se o seu caso de uso for mais complicado do que parece no exemplo (ou seja, você tem </form> tags na mesma linha de <cfoutput> ou </cfoutput> tags), é melhor procurar um analisador de HTML. Caso contrário, isso funcionará bem.

Usando 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 script expandido:

/<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>/ : executa a seguinte instrução (composta) somente se o registro atual estiver entre um registro contendo uma string <cfoutput> e um registro contendo uma string </cfoutput> ;
  • sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"#STOKEN#\"/>", $0); : substitui todas as ocorrências de </form> no registro atual por <input type="hidden" name="_token" value="#STOKEN#"/> ;
  • print : imprime o registro atual
  • next : pula para o próximo registro
  • sub(/<\/form>/, "<input type=\"hidden\" name=\"_token\" value=\"<cfoutput>#STOKEN#</cfoutput>\"/>", $0); : substitui todas as ocorrências de </form> no registro atual por <input type="hidden" name="_token" value="<cfoutput>#STOKEN#</cfoutput>"/> ;
  • print : imprime o registro atual
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>
    
por kos 24.08.2015 / 17:41