perl -pe 's/instant/$& . ++$n/ge'
ou com o GNU awk
:
awk -vRS=instant '{$0=n$0;ORS=RT}++n'
Para editar os arquivos no local, adicione a opção -i
a perl
:
perl -pi -e 's/instant/$& . ++$n{$ARGV}/ge' ./*
Ou recursivamente:
find . -type f -exec perl -pi -e 's/instant/$& . ++$n{$ARGV}/ge' {} +
Explicações
perl -pe 's/instant/$& . ++$n/ge'
-p
é processar a entrada linha por linha, avaliar a expressão passada para -e
para cada linha e imprimi-la. Para cada linha, substituímos (usando o s/re/repl/flags
operator) instant
por si mesmo ( $&
) e o valor incrementado de uma variável ++$n
. O g
flag é para fazer a substituição globalmente (não apenas uma vez) e e
para que a substituição seja interpretada como código perl para e̲ valuate (não uma string fixa).
Para edição no local em que uma chamada perl processa mais de um arquivo, queremos que $n
seja redefinido em cada arquivo. Em vez disso, usamos $n{$ARGV}
(onde $ARGV
é o arquivo atualmente processado).
O awk
merece um pouco de explicação.
awk -vRS=instant '{$0=n$0;ORS=RT}++n'
Estamos usando a capacidade do GNU awk
para separar registros em strings arbitrárias (até mesmo expressões regulares). Com -vRS=instant
, definimos o r̲ecord s̲eparator como instant
. RT
é a variável que contém o que foi correspondido por RS
, então, normalmente, instant
, exceto pelo último registro em que será a sequência vazia. Na entrada acima, os registros ( $0
) e os terminadores de registro ( RT
) são ( [$0|RT]
):
[test |instant][ ()
test |instant][ ()
...
test |instant][ () //total 1000 lines|]
Portanto, tudo o que precisamos fazer é inserir um número incremental no início de cada registro, exceto o primeiro.
O que fazemos acima. Para o primeiro registro, n
estará vazio. Nós definimos ORS (o o̲utput r̲ecord s̲eparator ) como RT, de forma que awk
imprime n $0 RT
. Ele faz isso na segunda expressão ( ++n
) que é uma condição que sempre é avaliada como verdadeira (um número diferente de zero) e, portanto, a ação padrão (de impressão $0 ORS
) é executada para cada registro.