Arquivo original
claudio
antonio
claudio
michele
Quero alterar apenas a primeira ocorrência de "claudio" por "claudia" para que o resultado do arquivo
claudia
antonio
claudio
michele
eu tentei
sed -e '1,/claudio/s/claudio/claudia/' nomi
Mas faça uma substituição global.
info sed
: (0,/REGEXP/
: Um número de linha de 0 pode ser usado em uma especificação de endereço como0,/REGEXP/
de modo quesed
vai tentar igualar REGEXP na primeira linha de entrada demasiado Em outras palavras,.0,/REGEXP/
É semelhante a1,/REGEXP/
, exceto que se o ADDR2 corresponder à primeira linha de entrada, o formulário 0, / REGEXP / considerará que ele encerra o intervalo, enquanto o formulário 1, / REGEXP / corresponderá ao início do seu intervalo e, portanto, aumentará o alcance. até a segunda ocorrência da expressão regular)awk '/claudio/ && !ok { sub(/claudio/,"claudia"); ok=1 } 1' nomi
deve fazer #Respostas:
Se você estiver usando o GNU
sed
, tente:sed
não inicia a verificação do regex que termina um intervalo até depois da linha que inicia esse intervalo.De
man sed
(página de manual do POSIX, ênfase minha):Usando
awk
Varia no
awk
trabalho mais do que você esperava:Explicação:
NR==1,/claudio/
Esse é um intervalo que começa com a linha 1 e termina com a primeira ocorrência de
claudio
.sub(/claudio/, "claudia")
Enquanto estamos no intervalo, este comando substituto é executado.
1
Esta abreviação enigmática deste awk para imprimir a linha.
fonte
sed
entanto.awk '!r && /claudio/ {sub(/claudio/,"claudia"); r=1} 1'
awk !x{x=sub(/claudio/,"claudia")}1
0,/claudio/
Aqui estão mais dois esforços programáticos com o sed: ambos lêem o arquivo inteiro em uma única sequência, então a pesquisa substituirá apenas a primeira.
Com comentários:
fonte
Uma nova versão do GNU
sed
suporta a-z
opção.Você pode usar esta opção quando quiser
sed
trabalhar em linhas diferentes.retorna
fonte
Você pode usar
awk
com um sinalizador para saber se a substituição já foi feita. Caso contrário, continue:fonte
Na verdade, é muito fácil se você apenas configurar um pequeno atraso - não é necessário procurar extensões não confiáveis:
Isso apenas adia a primeira linha para a segunda e a segunda para a terceira e etc.
Imprime:
fonte
E mais uma opção
A vantagem é que ele usa aspas duplas, para que você possa usar variáveis dentro, ou seja.
fonte
Isso também pode ser feito sem o espaço de espera e sem concatar todas as linhas no espaço do padrão:
Explicação: Tentamos encontrar "claudio" e, se o fizermos, pulamos no pequeno loop de carga de impressão entre
:x
ebx
. Caso contrário, imprimiremos e reiniciaremos o script com a próxima linha.fonte
fonte
Sumary
Sintaxe GNU:
Ou mesmo (para usar apenas uma vez a palavra a ser substituída:
Ou, na sintaxe POSIX:
funciona em qualquer sed, processa apenas quantas linhas
claudio
forem necessárias para encontrar a primeira , funciona mesmo queclaudio
esteja na primeira linha e é mais curto, pois usa apenas uma sequência de expressões regulares.Detalhe
Para alterar apenas uma linha, você precisa selecionar apenas uma linha.
O uso de
1,/claudio/
(da sua pergunta) seleciona:claudio
.Para selecionar qualquer linha que contenha
claudio
, use:E para selecionar apenas o primeiro
claudio
no arquivo, use:Em seguida, você pode fazer uma substituição somente nessa linha:
O que alterará apenas a primeira ocorrência da correspondência de regex na linha, mesmo que possa haver mais de uma, na primeira linha que corresponda à regex.
Obviamente, a
/claudio/
regex poderia ser simplificada para:E, então, a única coisa que falta é imprimir todas as outras linhas sem modificação:
fonte