Estou planejando substituir certas strings em um arquivo; então estou usando sed.
Eu gostaria que a string fosse substituída e, em vez disso, sed lesse a string e anexe o texto no meio da string.
Exemplo:
string in myfile : user=blabla
string that I want to obtain: user=bob
então eu executo o sed desta forma, para que ele procure pela string "user=" e substitua-a por "user=bob"
sed -i 's/user=*/user=bob/' myfile
O que eu consigo é
user=bobblabla
Basicamente, sed pensa que quero substituir apenas essa parte, enquanto quero substituir a string inteira pela nova string. Eu pensei que * diria ao sed para considerar qualquer coisa que viesse depois, mas não funcionou.
Como não sei o que será o "blabla", não posso colocá-lo no comando sed. Como posso dizer ao sed para encontrar uma string que comece com "user=" e substituir a string inteira pela nova?
Responder1
Você parece estar confundindo padrões de shell com expressões regulares. Em um padrão shell, *
significa zero ou mais de qualquer caractere. Numa expressão regular, que é o que sed
espera em seus padrões, *
significa zero ou mais do átomo anterior. No seu exemplo, esse átomo é o =
. Portanto, sed
está procurando user
seguido de zero ou mais =
e substituindo a string correspondente por user=bob
. O padrão que você deseja é user=.*
, que é user=
seguido por qualquer caractere ( .
) zero ou mais vezes, fazendo seu sed
comando:
sed -i 's/user=.*/user=bob/' myfile
Responder2
Como GaryJohn disse, você errou no regex. (* -> .*)
Mas eu iria um pouco mais longe, enquanto você está nisso... Não sei como é realmente o seu arquivo, mas apenas para praticar, gostaria de tornar sua operação de pesquisa/substituição um pouco mais segura.
Digamos que você queira executar a coisa em um arquivo como este:
user=john
superuser=jimmy # don't want to change this line!
user=L33t_us3rn4m3 # that should work too, and these comments should remain intact as well, btw
# in the line below, I want to change user=hello to user=bob
# but in the comments, "user=hello" should remain intact
user=hello
Com sua sintaxe sed atual, isso daria muito errado. Para torná-lo um pouco mais específico, você pode tentar:
sed -i 's/^user=[A-Za-z0-9_]*/user=bob/g' /tmp/myfile
Isso vai:
- só é acionado quando a linha realmente começa com "usuário" (o ^)
- altere apenas "user=" se consistir em 0 ou mais letras, dígitos ou sublinhados
- deixe tudo atrás do nome de usuário (ou seja, os comentários no meu exemplo) intacto
Isso não é de forma alguma algo superseguro que funcionará sempre e em qualquer lugar onde você deseja renomear usuários. Obviamente, isso depende de como seu arquivo de configuração está configurado e do que você esperaria encontrar. Mas minha resposta pretende dar um pouco de "alimento para reflexão", porque dado um (número de) arquivos de configuração grandes o suficiente para esperar que tantos nomes de usuários não queiram fazer isso manualmente, substituindo cegamente "user=.* "parece possivelmente perigoso. Você pode querer gastar algum tempo aprimorando esses tipos de operações :)
Boa sorte.