- Sua tentativa não funciona porque
==
testa apenas a igualdade exata. Se o seu arquivo continha uma linha que dizia exatamente e literalmenteTIMEOUT=[0-9]
, seu código reconheceria (e mude paraTIMEOUT=[5-9]
). Mas, como você viu, não corresponde a strings comoTIMEOUT=42
. Você, claro, quer selecionar linhas que correspondem ao padrãoTIMEOUT=number
. Uma maneira de fazer isso é usar o operador~
em vez de==
:awk '$0 ~ "TIMEOUT=[0-9]" { action statement(s) }'
- É bom entender como usar o operador
~
e saber que você pode fazer testes em campos individuais. Contudo, Há uma notação abreviada para corresponder a linha inteira a um padrão:awk '/TIMEOUT=[0-9]/ { action statement(s) }'
e você pode querer usar isso quando puder. - Então, agora, se fizermos
awk '/TIMEOUT=[0-9]/ { sub ("[0-9]","5") } { print }'
corresponderá à linhaTIMEOUT=200
- e altere paraTIMEOUT=500
, porque[0-9]
corresponde apenas a um único dígito (numeral) e não um número de vários dígitos. Para encontrar (e substituir) um número com vários dígitos (uma sequência de um ou mais numerais consecutivos), use o caractere+
(operador), que significa “uma ou mais ocorrências do padrão precedente”, como emsub ("[0-9]+","5")
. - Mas eu encarei um problema anteriormente nesta lista.
Embora
==
teste a igualdade exata da sequência completa ,~ "pattern"
e %código% teste para uma string contendo uma substring que corresponda ao padrão. Então, por exemplo,/pattern/
irá coincidir com uma linha que se pareceIn American football, a TIMEOUT=30seconds
Se estiver tudo bem com você, tudo bem. Eu imagino que você queira combinar apenas uma linha completa, então você vai querer "ancorar" o padrão para que/TIMEOUT=[0-9]/
esteja no começo da linha, e o número deve estar no final. Você faz isso com os caracteresTIMEOUT
e^
, como em$
.
Exceto… - … conforme mencionado anteriormente,
/^TIMEOUT=[0-9]$/
corresponde apenas a um único dígito, então, o que está acima corresponderá a[0-9]
, mas não aTIMEOUT=7
. Você precisa deTIMEOUT=11
.
TL; DR
Você precisa fazer
awk '$0 ~ "^TIMEOUT=[0-9]+$" { sub ("[0-9]+","5") } { print }' fileou
awk '/^TIMEOUT=[0-9]+$/ { sub ("[0-9]+","5") } { print }' file
Incentivo você a aprender /^TIMEOUT=[0-9]+$/
, pois pode ser muito útil e muito poderoso.
No entanto, para uma tarefa simples como essa,
você pode obter uma ferramenta mais simples: awk
.
Infelizmente,
sed
normalmente não suporta o operador sed
(um ou mais).
No GNU +
(a versão que vem com o Cygwin
e a maioria (se não todas) distribuições Linux),
você pode especificar a opção sed
para dizer para reconhecer "expressões regulares estendidas".
(Padrões como -r
são chamados de "expressões regulares".)
Então você poderia fazer
sed -r '/^TIMEOUT=[0-9]+$/s/[0-9]+/5/'
Mas algumas versões (mais antigas) de [0-9]+
não honram a opção sed
e não suportam expressões regulares estendidas.
Felizmente, você pode contornar isso:
há outro caractere especial (operador), -r
,
que significa “ zero ou mais ocorrências do padrão anterior”.
"Um ou mais dígitos" é equivalente a
"Um dígito, seguido por zero ou mais dígitos adicionais"
então podemos traduzir *
para [0-9]+
e fazer o comando como
sed '/^TIMEOUT=[0-9][0-9]*$/s/[0-9][0-9]*/5/'
Em vez de [0-9][0-9]*
, você também pode fazer [0-9][0-9]*
(um dígito, precedido por zero ou mais dígitos adicionais).
Eu prefiro a segunda forma, porque eu acho que parece mais equilibrado,
mas não é muito popular.