Seleção de linha a partir do padrão, substituição por nova linha e número de incremento para cada mudança

1

Oi eu estou tentando descobrir como selecionar uma linha em um arquivo de texto de uma seqüência de caracteres padrão / palavra e, em seguida, substituir essa linha com novo texto com um número incremental para cada linha alterada.

Eu estava planejando usar sed, mas não tenho ideia de como implementar o número crescente de cada linha alterada.

O objetivo, antes e depois:

Texto antes:

">text_1_lots of other bits of text"   
other lines of text   
">text_2_lots of other bits of text"    
other lines of text   
">text_3_lots of other bits of text"   
other lines of text  

Texto depois:

">text_1"   
other lines of text   
">text_2"    
other lines of text   
">text_3"   
other lines of text  

Isso é o que eu tenho até agora:

sed -i "s/>text_*/>text_[0-n]/g"   

Eu percebo que isso não funciona, pois o [0-n] e o curinga * estão apenas representando o que estou tentando fazer, e são as coisas mais próximas que consigo pensar para conseguir isso (embora eu entenda isso é essencialmente pseudo código no momento)

    
por Giles 08.07.2016 / 22:49

3 respostas

3

Com base na sua tentativa com sed, parece que o patten que você está tentando corresponder é ">text_ e você deseja anexar um número e um " depois disso

Isso é possível com awk .

awk 'BEGIN {cnt=1} /^">text_/ { gsub("_.*$","_"cnt++"\"",$0) } { print}'

por exemplo,

$ cat x
">text_lots of other bits of text"
other lines of text
">text_lots of other bits of text"
other lines of text
">text_lots of other bits of text"
other lines of text

$ awk 'BEGIN {cnt=1} /^">text_/ { gsub("_.*$","_"cnt++"\"",$0) } { print}' x
">text_1"
other lines of text
">text_2"
other lines of text
">text_3"
other lines of text

Você pode alterar o padrão de pesquisa ^"text_ para identificar as linhas que deseja alterar e a gsub() fará a substituição; neste caso, do primeiro _ até o final da linha, é substituído por _ , em seguida, a contagem é então uma "

    
por 08.07.2016 / 23:05
2

perl pode fazer isso com uma sintaxe semelhante à de sed , mas permitindo uma avaliação direta do índice de substituição, por exemplo

perl -pe 's/>text_.*/sprintf "text_%d", ++$n/pe' file

Veja também Substitua a string pelo índice sequencial .

No entanto, como no seu caso o texto já está numerado, é mais fácil aparar a parte indesejada, capturando e reubstituindo-a - por exemplo

sed -E 's/(>text_[0-9]{1,}).*//' file
    
por 08.07.2016 / 23:38
2

Eu acho que o mais fácil seria usar bash ou perl. Exemplo básico simples que deve ajudá-lo com seu problema provavelmente mais complicado:

$ cat script 
#!/bin/bash
i=1
while read a ; do
    if [[ "$a" =~ "\">text_${i}".* ]]
    then echo "\">text_${i}\"" ; i=$((i+1))
    else echo "$a"
    fi
done
$ cat input 
">text_1_lots of other bits of text"
other lines of text
">text_2_lots of other bits of text"
other lines of text
">text_3_lots of other bits of text"
other lines of text
$ cat input | bash script 
">text_1"
other lines of text
">text_2"
other lines of text
">text_3"
other lines of text
    
por 08.07.2016 / 23:20