Sed - substitui um personagem em uma linha correspondente no lugar?


21

Em um arquivo contendo linhas como esta:

# lorem ipsum blah variable

Gostaria de remover o #caractere (comentário) na mesma linha que contém uma sequência específica, no lugar. Isso é sedbom para isso?

Estou lutando para obter esse trabalho condicional. Eu tenho uma maneira "desajeitada" de fazer isso; Posso encontrar o número da linha correspondente com awkou sede depois usá-lo em um sedcomando separado , mas acredito que isso pode ser feito de uma maneira muito melhor.

Respostas:


36

Use a string que você procura como seletor para as linhas a serem operadas:

sed '/ipsum/s/#//g'

/ipsum/seleciona linhas contendo "ipsum" e somente nessas linhas os comandos a seguir são executados. Você pode usar chaves para executar mais comandos

/ipsum/{s/#//g;s/@/-at-/g;}

4
Concordo; esta é a melhor resposta (embora não seja a única). Comentários: (1) 's/#//g'removerá todos os #caracteres da linha. Se não é isso que você deseja, remova o g(que significa "global"). (2) Para editar um arquivo no local (conforme solicitado na pergunta), use sed -i.
G-Man diz 'Reinstate Monica'

2
(3) Por uma questão de situações do mundo real, se você deseja cancelar o comentário de uma linha, pode usar sed -i '/ipsum/s/#[[:space:]]*//', para se livrar de quaisquer espaços e guias imediatamente após o #. (4) Você também pode verificar se esse #é o primeiro caractere que não está em branco na linha. O comando atual excluiria o #da linha prompt "Enter # of ipsums:".
G-Man diz 'Reinstate Monica'

11
@ G-Man - ótimo complemento! Para o seu 2º pt (espaço à esquerda), que tal: sed -i '/ipsum/s/^#[[:space:]]*//'?! ( ^Significa o início da linha, $para fim de linha) - pelo menos no GNU sed ...
Jeremy Davis

11
@ JeremyDavis: Sim, você pode ancorar o regex no início da linha ^, mas isso seria errado. Costumo comentar o código recuado colocando o #imediatamente antes do código, para que o #recuo seja feito. Duvido que eu seja a única pessoa que faz isso.
G-Man diz 'Reinstate Monica'

11
@ G-Man - ah sim, é claro! Obrigado, eu não tinha considerado isso. Então você também gostaria de verificar se há espaço em branco entre ^& #, então algo mais parecido com isto: /ipsum/{/^[[:space:]]*#/s/#[[:space:]]*//}. Embora mesmo assim, dependendo de onde #esteja, ele ainda possa causar problemas (por exemplo, em idiomas que usam recuo / separação de espaço em branco).
Jeremy Davis

7
$ cat input.txt
# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
# lorem ipsum blue variable

então:

$ sed 's|# \(.*blue.*\)|\1|' input.txt

dá:

# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
lorem ipsum blue variable

Funciona da seguinte maneira:

O sdiz sedque ele deve substituir o que a expressão regular encontra.

O padrão é # \(.*blue.*\)dividido em: Encontre um hash seguido por um espaço. O colchete ( \() inicia o agrupamento. .*blue.*é a palavra bluecom qualquer coisa antes e depois. O próximo colchete ( \)) fecha o agrupamento.

A substituição é \1uma referência retroativa ao conteúdo do primeiro suporte de agrupamento.


3

Você pode usar o Vim no modo Ex:

ex -sc '/ipsum/s/#//|x' file
  1. s substituto

  2. x salvar e fechar


Isso é bem legal. Eu não sabia disso! TBH, não tenho certeza se é a melhor resposta para esta pergunta (IMO, a principal resposta sed é a única), mas ainda é muito legal! Obrigado por publicar.
Jeremy Davis
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.