Como posso encontrar e substituir palavras específicas em um arquivo de texto usando a linha de comando?
command-line
text-processing
Jon Doe
fonte
fonte
Respostas:
Explicação:
sed
= Stream EDitor-i
= no local (ou seja, salve de volta no arquivo original)A cadeia de comando:
s
= o comando substitutooriginal
= uma expressão regular que descreve a palavra a substituir (ou apenas a própria palavra)new
= o texto para substituí-lo porg
= global (isto é, substitua tudo e não apenas a primeira ocorrência)file.txt
= o nome do arquivofonte
sed
, eles corresponderão a eles. Adicione uma-r
bandeira se desejar usar REs estendidos./
caractere que você precisa corresponder, você pode usar outro caractere como separador (por exemplo's_old/text_new/text_g'
). Caso contrário, você pode colocar um\
antes de qualquer um$ * . [ \ ^
para obter o caractere literal.sed -i '.bak' 's/original/new/g' file.txt
também pode ser executado com uma extensão de comprimento zerosed -i '' 's/original/new/g' file.txt
, que não gerará backup.Existem várias maneiras diferentes de fazer isso. Um está usando
sed
e Regex. O SED é um editor de fluxo para filtrar e transformar texto. Um exemplo é o seguinte:Outra maneira que pode fazer mais sentido do que
< strin
e> strout
é com canos!fonte
cat
nocat file | sed '...'
é desnecessário. Você pode dizer diretamentesed '...' file
.sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly
levará o arquivo rapidamente e fará as duas alterações no local enquanto faz um backup. Usando otime bash -c "$COMMAND"
tempo, sugere que esta versão é ~ 5 vezes mais rápida.Existem várias maneiras de conseguir isso. Dependendo da complexidade do que se tenta obter com a substituição de cadeias, 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 um
input.txt
arquivo simples , que você pode usar para testar todos os exemplos fornecidos aqui. O conteúdo do arquivo:BATER
O Bash não é realmente destinado ao processamento de texto, mas substituições simples podem ser feitas via expansão de parâmetros , em particular aqui podemos usar estrutura simples
${parameter/old_string/new_string}
.Esse pequeno script não substitui no local, o que significa que você precisaria salvar o novo texto em um novo arquivo e se livrar do arquivo antigo, ou
mv new.txt old.txt
Nota lateral: se você está curioso para saber por que
while IFS= read -r ; do ... done < input.txt
é usado, é basicamente a maneira do shell de ler o arquivo linha por linha. Veja isto para referência.AWK
O AWK, sendo um utilitário de processamento de texto, é bastante apropriado para essa tarefa. Pode fazer substituições simples e muito mais avançadas com base em expressões regulares . Ele fornece duas funções:
sub()
egsub()
. O primeiro substitui apenas a primeira ocorrência, enquanto o segundo substitui ocorrências em toda a cadeia. Por exemplo, se tivermos stringone potato two potato
, este seria o resultado:O AWK pode usar um arquivo de entrada como argumento; assim, fazer as mesmas coisas
input.txt
seria fácil:Dependendo da versão do AWK que você possui, ela pode ou não ter edição no local; portanto, a prática usual é salvar e substituir o novo texto. Por exemplo, algo como isto:
SED
Sed é um editor de linha. Ele também usa expressões regulares, mas para substituições simples é suficiente:
O que há de bom nessa ferramenta é que ela possui edição no local, que você pode ativar com o
-i
sinalizador.Perl
O Perl é outra ferramenta frequentemente usada para processamento de texto, mas é uma linguagem de uso geral e é usada em redes, administração de sistemas, aplicativos de desktop e muitos outros locais. Ele emprestou muitos conceitos / recursos de outras linguagens como C, sed, awk e outros. A substituição simples pode ser feita da seguinte maneira:
Como sed, o perl também tem a bandeira -i.
Pitão
Esse idioma é muito versátil e também é usado em uma ampla variedade de aplicações. Ele tem muitas funções para trabalhar com strings, entre as quais
replace()
, portanto, se você tiver variáveis comovar="Hello World"
, poderá fazervar.replace("Hello","Good Morning")
A maneira simples de ler o arquivo e substituir a string seria assim:
No entanto, com o Python, você também precisa gerar um novo arquivo, o que também pode ser feito no próprio script. Por exemplo, aqui está um exemplo simples:
Este script deve ser chamado
input.txt
como argumento da linha de comando. O comando exato para executar o script python com argumento da linha de comando seriaou
Obviamente, verifique se ele
./myscript.py
está no seu diretório de trabalho atual e, pela primeira vez, verifique se ele está definido como executável comchmod +x ./myscript.py
O Python também pode ter expressões regulares, em particular, existe um
re
módulo, que temre.sub()
função, que pode ser usado para substituições mais avançadas.fonte
tr
comando no unixtr
é outra ótima ferramenta, mas observe que é para substituir conjuntos de caracteres (por exemplotr abc cde
, traduzira
parac
,b
parad
. É um pouco diferente de substituir palavras inteiras como comsed
oupython
Você pode usar o Vim no modo Ex:
%
selecione todas as linhass
substitutog
substitua todas as instâncias em cada linhax
escreva se as alterações foram feitas (elas têm) e saiafonte
Através do comando gsub do awk,
Exemplo:
No exemplo acima, todos os 1s são substituídos por 0, independentemente da coluna em que ela se localizou.
Se você deseja fazer uma substituição em uma coluna específica, faça o seguinte,
Exemplo:
Ele substitui 1 por 0 apenas na primeira coluna.
Através do Perl,
fonte
inotifywait
sobsh
env, e comunicação de dados em formato CSV (porque formato personalizado é buggy). Eu então imaginei que não havia uma maneira simples de lidar com documentos CSV em scripts de shell ... E eu quero muito leve. Então, iniciei um script bastante simples para analisar e relatar CSV. Li a especificação CSV e notei que ela é mais elaborada do que eu esperava e apóio o valor de várias linhas envolto em aspas duplas. Eu estava contando comsed
a tokenização, mas logo percebi que mesmo o quesed
chamam multilinhas é de até duas linhas. E se um dos meus valores de CSV se estender por mais de duas linhas?sed
é o s tream ed itor , em que você pode usar|
(pipe) para enviar fluxos padrão (STDIN e STDOUT especificamente) através desed
e alterá-los por meio de programação em tempo real, tornando-se uma ferramenta útil na filosofia tradição Unix; mas também pode editar arquivos diretamente, usando o-i
parâmetro mencionado abaixo.Considere o seguinte :
s/
é utilizado para s ubstitute a expressão encontradofew
comasd
:/g
significa "global", o que significa fazer isso para toda a linha. Se você deixar de/g
(coms/few/asd/
, sempre precisará haver três barras, não importa o que) efew
aparecer duas vezes na mesma linha, somente a primeirafew
será alterada paraasd
: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 o material anterior nos threads de email por uma guia horizontal, deixando uma desigualdade algébrica entre aspas mais adiante. intocado), mas no seu exemplo em que você especifica que em qualquer lugar
few
ocorre, ele deve ser substituído, verifique se possui/g
.As duas opções a seguir (sinalizadores) são combinadas em uma
-ie
:-i
opção é usada para editar i n colocar no arquivohello.txt
.-e
opção indica o e xpression / comando para executar, neste casos/
.Nota: É importante que você use
-i -e
para pesquisar / substituir. Nesse caso-ie
, você cria um backup de cada arquivo com a letra 'e' anexada.fonte
Você pode fazer assim:
Exemplos: para substituir todas as ocorrências [logdir ',' '] (sem []) por [logdir', os.getcwd ()] em todos os arquivos resultantes do comando Locate, faça:
ex1:
ex2:
onde [tensorboard / program.py] é um arquivo para pesquisar
fonte
logdir', ''
->/logdir', os.getcwd()
) dificulta a análise desta resposta. Além disso, vale a pena especificar que sua resposta primeiro localiza os arquivos a serem usados no sed, porque isso não faz parte da pergunta.