Usando sed para editar linhas em um arquivo com uma variável

3

Eu preciso editar linhas em um arquivo usando sed . Agora, o problema é que estou substituindo um padrão específico por uma combinação de texto e número. Este número é uma variável que continua incrementando para cada linha subseqüente. Agora, como sed executa o comando para todas as linhas de uma só vez, ele está substituindo o padrão encontrado com o texto e o número fixo (ou seja, o valor inicial do número).

Por exemplo:

k = 10
sed "s/raj/ram${k++}/"
    
por rajsekhar 30.08.2011 / 10:10

3 respostas

2

Se o seu arquivo for muito pequeno, isso pode funcionar:

#!/bin/bash
for n in {1..40}
do
    sed -i $n's/raj/ram'$n'/' file
done 

Ele itera o arquivo 40 vezes e sempre substitui apenas 1 linha. Se você quer incrementar um contador não pelo número da linha, mas pelo número de linhas que você mudou, você tem que fazer diferente, com 2 variáveis, mas o comando sed seria similar - n não seria definido pelo loop .

sed -i altera o arquivo no lugar, então se você quiser manter o original, você tem que fazer uma cópia primeiro.

Isso pode ser feito em um oneliner, se você preferir:

for n in {1..40}; do sed -i $n's/raj/ram '$n'/' file ; done

Também é possível escolher o tamanho correto em vez de 40 automaticamente.

    
por 30.08.2011 / 12:49
2
awk -v n=10 '{sub(/raj/, "ram" n); print; n++}'
    
por 30.08.2011 / 15:18
1

Há momentos para usar sed e há momentos para não usá-lo.
Como sed não possui aritmética interna, use outra coisa.
Você pode hackear sed para fazê-lo (sem loop), mas é um tanto desnecessário e um pouco bagunçado comparado a usar algo mais adequado.

Com esses dados de entrada:

printf '%s\n' 'a.raj' 'yyy' 'zzz' 'b.raj c.raj' >file
num=10 # start with this value

Aqui está um método perl, que incrementa cada e toda ocorrência de raj (não apenas uma vez por linha combinada)

perl -pe 'BEGIN{ $num='$((num-1))' }
          s/raj/ram.($num+=1)/ge' file

saída:

a.ram10
yyy
zzz
b.ram11 c.ram12

Aqui está outra versão perl , que incrementa raj apenas uma vez por linha combinada (ou seja, várias correspondências na mesma linha têm o mesmo sufixo numérico).

perl -pe 'BEGIN{ $num='$num' }
          if(/raj/){ s/raj/ram.$num/ge; $num+=1 }' file

saída:

a.ram10  
yyy  
zzz  
b.ram11 c.ram11  

veja: Quando NÃO devo usar sed

    
por 30.08.2011 / 14:58

Tags