Localizar e substituir texto dentro de um arquivo usando comandos

Como posso encontrar e substituir palavras específicas em um arquivo de texto usando a linha de comando?

sed -i 's/original/new/g' file.txt

Explicacao:

  • sed = Editor De Fluxo
  • -i = in-place (ou seja, salvar de volta para o arquivo original)
  • A cadeia de comando:

    • s = comando substituto
    • original = uma expressão regular que descreve a palavra a substituir (ou apenas a própria palavra)
    • new = o texto para substituí-lo por
    • g = global (ou seja, substituir tudo e não apenas a primeira ocorrência)
  • file.txt = o nome do arquivo

Há uma infinidade de maneiras de alcançá-lo. Dependendo da complexidade do que se tenta alcançar com a substituição de string e, dependendo das ferramentas com as quais o usuário está familiarizado, alguns métodos podem ser preferidos mais do que outros.

Nesta resposta estou usando simples input.txt arquivo, que você pode usar para testar todos os exemplos fornecidos aqui. O conteúdo do arquivo:

roses are red , violets are blueThis is an input.txt and this doesn't rhyme

BATER

Bash não é realmente destinado ao processamento de texto, mas substituições simples podem ser feitas via expansão do parâmetro , em particular aqui podemos usar estrutura simples ${parameter/old_string/new_string}.

#!/bin/bashwhile IFS= read -r linedo    case "$line" in       *blue*) printf "%s\n" "${line/blue/azure}" ;;       *) printf "%s\n" "$line" ;;    esacdone < input.txt

Este pequeno script não faz substituição no local, o que significa que você teria que salvar um novo texto em um novo arquivo e se livrar do arquivo antigo, ou mv new.txt old.txt

Nota lateral: se você está curioso sobre o porquê while IFS= read -r ; do ... done < input.txt é usado, é basicamente a maneira do shell de ler o arquivo linha por linha. Ver presente para referência.

AWK

AWK, sendo um utilitário de processamento de texto, é bastante apropriado para essa tarefa. Ele pode fazer substituições simples e muito mais avançadas com base em jargao. Ele fornece duas funções: sub() e gsub(). O primeiro só substitui apenas a primeira ocorrência, enquanto o segundo-substitui ocorrências em string inteira. Por exemplo, se tivermos string one potato two potato , este seria o resultado:

$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'one banana two banana$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'                                      one banana two potato 

AWK pode levar um arquivo de entrada como argumento, fazendo as mesmas coisas com input.txt , seria fácil:

awk '{sub(/blue/,"azure")}1' input.txt

Dependendo da versão do AWK que você tem, ele pode ou não ter edição no local, portanto, a prática usual é salvar e substituir novo texto. Por exemplo, algo assim:

awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt

SED

Sed é um editor de linha. Ele também usa expressões regulares, mas para substituições simples é suficiente fazer:

sed 's/blue/azure/' input.txt

O que há de bom nessa ferramenta é que ela possui edição no local, que você pode habilitar com -i bandeira.

Perl

Perl é outra ferramenta que é frequentemente usada para processamento de texto, mas é uma linguagem de uso geral e é usada em Rede, Administração de sistemas, aplicativos de desktop e muitos outros lugares. Ele emprestou muitos conceitos / recursos de outras linguagens,como C,sed, awk e outros. A substituição simples pode ser feita assim:

perl -pe 's/blue/azure/' input.txt

Como sed, perl também tem a bandeira-I.

Jiboia

Esta linguagem é muito versátil e também é usada em uma ampla variedade de aplicações. Tem muitas funções para trabalhar com strings, entre as quais replace(), então se você tem variável como var="Hello World" , você poderia fazer var.replace("Hello","Good Morning")

Maneira simples de ler o arquivo e substituir a string nele seria assim:

python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt

Com o Python, no entanto, você também precisa enviar para um novo arquivo , o que também pode ser feito de dentro do próprio script. Por exemplo, aqui está um simples:

#!/usr/bin/env pythonimport sysimport osimport tempfiletmp=tempfile.mkstemp()with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:    for line in fd1:        line = line.replace('blue','azure')        fd2.write(line)os.rename(tmp[1],sys.argv[1])

Este script deve ser chamado com input.txt como argumento de linha de comando. O comando exato para executar script python com argumento de linha de comando seria

 $ ./myscript.py input.txt

ou

$ python ./myscript.py input.txt

Claro, certifique-se de que ./myscript.py está em seu diretório de trabalho atual e, pela primeira vez, certifique-se de que está definido executável com chmod +x ./myscript.py

Python também pode ter expressões regulares, em particular, há re módulo, que tem re.sub() função, que pode ser usada para substituições mais avançadas.

Existem várias maneiras diferentes de fazer isso. Um está usando sed e Regex. SED é um editor de fluxo para filtrar e transformar texto. Um exemplo é o seguinte:

marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orlymarco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarlymarco@imacs-suck: ~$ cat yarlyThe quick brown unicorn jumped over the hyper sleeping dog

Outra maneira que pode fazer mais sentido do que < strin e > strout é com tubos!

marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowaimarco@imacs-suck: ~$ cat nowai The quick brown fox jumped over the lazy sleeping dog

Através do comando gsub da awk,

awk '{gsub(/pattern/,"replacement")}' file

Exemplo:

awk '{gsub(/1/,"0");}' file

No exemplo acima, todos os 1 são substituídos por 0, independentemente da coluna onde estão localizados.


Se você quiser fazer uma substituição em uma coluna específica, faça assim,

awk '{gsub(/pattern/,"replacement",column_number)}' file

Exemplo:

awk '{gsub(/1/,"0",$1);}' file

Ele substitui 1 por 0 apenas na primeira coluna.

Através Do Perl,

$ echo 'foo' | perl -pe 's/foo/bar/g'bar

Você pode usar o Vim no modo Ex:

ex -s -c '%s/OLD/NEW/g|x' file
  1. % Selecione Todas as linhas

  2. s substituir

  3. g substitua todas as instâncias em cada linha

  4. x escreva se as alterações foram feitas (elas foram feitas) e saia

sed é o stream disfuncaoitor, em que você pode usar | (tubo) para enviar fluxos padrão (Stdin e stdout especificamente) através de sed e alterá-los programaticamente em tempo real, tornando - se uma ferramenta útil na tradição da filosofia Unix; mas pode editar arquivos diretamente, também, usando o -i parâmetro mencionado abaixo.
Considerar:

sed -i -e 's/few/asd/g' hello.txt

s/ é usado para substitute a expressão encontrada few com asd:

Os poucos, os corajosos.


O asd, o bravo.

/g significa "global", o que significa fazer isso para toda a linha. Se você sair do /g (com s/few/asd/, sempre precisa haver três barras, não importa o que) e few aparece duas vezes na mesma linha, apenas o primeiro few é alterado para asd:

Os poucos homens, as poucas mulheres, os corajosos.


Os homens asd, as poucas mulheres, os bravos.

Isso é útil em algumas circunstâncias, como alterar caracteres especiais no início das linhas (por exemplo, substituir os símbolos maiores que algumas pessoas usam para citar material anterior em threads de E-mail por uma guia horizontal, deixando uma desigualdade algébrica citada mais tarde na linha intocada), mas em seu exemplo, onde você especifica que lugar few ocorre deve ser substituído, certifique-se de que você tem que /g.

As duas opções a seguir (sinalizadores) são combinadas em uma, -ie:

-i a opção é usada para editar in Coloque no arquivo hello.txt.

-e opção indica o expression / comando a ser executado, neste caso s/.

Nota: é importante que você use -i -e para pesquisar / substituir. Se você fizer -ie, você cria um backup de cada arquivo com a letra 'e' anexada.

Você pode fazer assim:

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 

Exemplos: para substituir todas as ocorrências [logdir',"] (sem [] ) por [logdir', os.getcwd()] em todos os arquivos que são resultado do comando locate, Faça:

ex1:

locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"

ex2:

locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"

onde [tensorboard/program.py] é arquivo para pesquisar