Como pesquisar e substituir várias agulhas por uma palavra através de uma expressão?

8

Suponha que você tenha um arquivo de texto:

foo fnord bar
bizz foo poit

E agora eu gostaria de substituir "foo" e "bar" em "narf".

Eu sei que eu poderia usar:

 sed -e 's/foo/narf/g' -e 's/bar/narf/g' fileName

No entanto, eu gostaria de trabalhar com um operador OR que diga ao regex para combinar as duas agulhas por meio de uma expressão.

Acertando alguns manuais, suponho que o tubo atenda às minhas necessidades, mas tentei

sed -e 's/foo|bar/narf/g' -i fileName

e não funcionou e nem está gerando um erro.

O que eu estou fazendo errado aqui?

k0pernikus
fonte

Respostas:

10

Use a -ropção para sintaxe regexp estendida:

sed -r -e 's/foo|bar/narf/g'

Caso contrário, escape da disjunção como \|:

sed -e 's/foo\|bar/narf/g'
Stéphane Gimenez
fonte
6

Existem muitas variações na sintaxe da expressão regular . As primeiras ferramentas no mundo unix que tinham expressões regulares não tinham todos os recursos de expressões regulares, apenas conjuntos de caracteres ( […]e .), repetição ( *) e âncoras de linha ( ^e $). Expressões regulares básicas possuem apenas esses operadores. Sed é uma ferramenta da velha escola e usa regexps básicos.

Muitas implementações sed possuem extensões para correspondência completa de regexp. Como o personagem |se destaca, você precisa usá-lo \|para alternar, da mesma forma \(e \)para agrupar. Note que o padrão POSIX não exige \|suporte a expressões regulares básicas , e alguns sistemas (por exemplo, OpenBSD ) não o possuem.

Algumas versões do sed têm a opção de alternar para expressões regulares estendidas , onde (…)é usado para agrupamento e |alternância. Com o GNU sed (ou seja, no Linux ou Cygwin) ou Busybox , passe a -ropção. No FreeBSD ou OSX , passe a -Eopção

Se o seu sed não tiver alternância, você pode ligar awk. É mandatado pelo POSIX , mas é um pouco detalhado para esta tarefa, e não suporta referências posteriores.

awk '{gsub(/foo|bar/, "narf")}' <fileName.old >fileName.new

A propósito, apenas o GNU e o Busybox sed suportam a substituição de arquivos. Awk e outras versões do sed não. Consulte Posso fazer o `cut` alterar um arquivo no lugar?

Se você possui o Perl, geralmente é útil de uma maneira que faz uma ferramenta única para o processamento de textos de uma linha. A maior parte do que é fácil em sed, awk e o resto não é muito mais difícil no Perl, e você pode aprender uma única ferramenta (se complexa).

perl -i -pe 's/foo|bar/narf/g' fileName
Gilles 'SO- parar de ser mau'
fonte
0

Você pode usar o Vim no modo Ex:

ex -sc '%s/\vPA|QU/RO/g|x' file
  1. % selecione todas as linhas

  2. s substituto

  3. \v ligue magia

  4. g substituição global

  5. x salvar e fechar

Steven Penny
fonte