Como truncar as linhas para um comprimento específico em um arquivo que ocorre entre padrões específicos?

Como truncar as linhas para um comprimento específico em um arquivo que ocorre entre padrões específicos?

Tenho vários arquivos nos quais preciso truncar apenas as linhas que ficam entre o padrão @TEST e enabled="true">. Quando há uma correspondência, a string entre @TESTe enabled="true">deve ter apenas 50 caracteres. Todas as outras linhas devem ser deixadas intactas.

Exemplo:

@TEST-TC_0010 @TEST Verifique se o servidor de contabilidade RADIUS não deve enviar a mensagem de resposta de contabilidade ao receber o pacote de solicitação de contabilidade do cliente RADIUS" enabled="true">

Eu tenho que mudar a linha acima como mostrado abaixo.

@TEST-TC_0010@TESTEVerifique se o servidor de contabilidade RADIUS não devehabilitado="verdadeiro">

Responder1

Neste caso, você pode usar grep com pesquisas em Perl.

grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile

A expressão "(?<=)" marca o ponto em que uma partida começará e a expressão "(?=)" é o ponto em que a partida termina.

O ".*" diz ao grep para retornar tudo entre os pontos inicial e final.

Usando sua entrada de teste, a linha acima retorna 157 caracteres.

$ echo "Verify that the RADIUS accounting server should not send the Accounting-Response Message on Receiving the Accounting-Request Packet from the RADIUS Client" | wc -m
157

Se você quiser truncar ainda mais para apenas os primeiros 50 caracteres, você pode usar cut

$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50
Verify that the RADIUS accounting server should no

Se desejar salvar os resultados em um arquivo, você precisará canalizar a saída para outro arquivo. Você pode usar algo como o seguinte ...

$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50 >> outputfile

Substituir o arquivo de entrada não é algo que eu recomendaria pessoalmente, pois talvez você precise usar os dados originais em algum momento.

Portanto, se você precisar manter todas as outras entradas no arquivo e truncar apenas as linhas em que enabled="true", precisaremos alterar as ferramentas para awk.

$ awk  -F'@TEST' '{if (/true/) print substr($3,2,50); else print $0}' inputfile >> outputfile

Este oneliner produzirá, sem alterações, todas as linhas que não correspondem a true. Quando true for correspondido, a linha será truncada para 50 caracteres. Novamente, eu não recomendo substituir os dados originais para que os resultados sejam canalizados para um arquivo de saída.

Com base nas edições mais recentes feitas na pergunta pelo OP, modifiquei o awk one-liner para replicar a saída fornecida pelo iniciante. Ele mencionou em seu comentário que o awk não funciona. Até que o OP forneça mais detalhes sobre por que o awk não funciona, ao usar o awk 4.1.3 no Ubuntu 16.04, a linha a seguir retornará os resultados que ele detalhou até agora.

awk  -F'@TEST' '{if (/true/) print "@TEST"$2,"@TEST",substr($3,2,50),"enabled=\"true\">"; else print $0}' inputfile >> outputfile

informação relacionada