Existem várias maneiras de conseguir isso. Dependendo da complexidade do que se tenta alcançar com a substituição de strings e dependendo das ferramentas com as quais o usuário está familiarizado, alguns métodos podem ser preferidos mais que outros.
Nesta resposta, estou usando o arquivo input.txt
simples, que você pode usar para testar todos os exemplos fornecidos aqui. O conteúdo do arquivo:
roses are red , violets are blue
This is an input.txt and this doesn't rhyme
BASH
O Bash não é realmente destinado ao processamento de texto, mas substituições simples podem ser feitas através da expansão de parâmetros , em particular aqui podemos usar estrutura simples ${parameter/old_string/new_string}
.
#!/bin/bash
while IFS= read -r line
do
case "$line" in
*blue*) printf "%s\n" "${line/blue/azure}" ;;
*) printf "%s\n" "$line" ;;
esac
done < input.txt
Este pequeno script não substitui o 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: se você está curioso para saber porque o while IFS= read -r ; do ... done < input.txt
é usado, é basicamente a maneira de o shell ler o arquivo linha por linha. Veja este para referência.
AWK
O 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 nas expressões regulares . Ele fornece duas funções: sub()
e gsub()
. O primeiro substitui apenas a primeira ocorrência, enquanto o segundo substitui as ocorrências em toda a cadeia. Por exemplo, se tivermos a string one potato two potato
, esse 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
O AWK pode usar um arquivo de entrada como argumento, portanto, fazer 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 uma edição no local, portanto, a prática usual é salvar e substituir o 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 linhas. Ele também usa expressões regulares, mas para substituições simples é suficiente:
sed 's/blue/azure/' input.txt
O que é bom nessa ferramenta é que ela possui uma edição no local, que você pode ativar com -i
flag.
Perl
Perl é outra ferramenta que é frequentemente usada para processamento de texto, mas é uma linguagem de propósito geral e é usada em redes, 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 da seguinte forma:
perl -pe 's/blue/azure/' input.txt
Como sed, o perl também tem o sinalizador -i.
Python
Esta linguagem é muito versátil e também é usada em uma ampla variedade de aplicativos. Ele tem muitas funções para trabalhar com strings, entre as quais replace()
, então se você tem uma variável como var="Hello World"
, você pode fazer var.replace("Hello","Good Morning")
Uma maneira simples de ler arquivos e substituir strings seria:
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
Com o Python, no entanto, você também precisa gerar um novo arquivo, o que também pode ser feito dentro do próprio script. Por exemplo, aqui está uma simples:
#!/usr/bin/env python
import sys
import os
import tempfile
tmp=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 Python também pode ter expressões regulares, em particular, há re
module, que tem re.sub()
function, que pode ser usado para substituições mais avançadas.