O comando sed é uma abreviação para stream editor. É uma ferramenta amplamente popular em sistemas Linux/UNIX. Sed não é um editor de texto por si só. No entanto, ele pode realizar várias modificações para manipular um determinado texto. A entrada de texto é enviada como um fluxo (stream). Sed então realiza as ações instruídas no fluxo. Este guia fornece uma visão geral do sed comando e como operá-lo para manipular texto com sucesso no Linux.
Sed no Linux
O fluxo de entrada do sed pode vir de um arquivo de texto ou de STDIN (entrada padrão). Podemos trabalhar com a saída de outro comando ou trabalhar diretamente com um arquivo de texto. A sed ferramenta vem pré-instalada em todas as Linux distribuições.
Visão Geral do Uso do Sed
O sed comando segue a seguinte estrutura:
|
1 |
$ sed <opções> <comandos> <arquivo> |
Para fins de demonstração, obtivemos a versão em texto da licença GPL versão 3:
|
1 |
$ wget https://www.gnu.org/licenses/gpl-3.0.txt |
O seguinte sed comando imprimirá o conteúdo do arquivo de texto:
|
1 |
$ sed '' gpl-3.0.txt |
Aqui, o sed está realizando as operações descritas entre aspas simples e imprimindo a saída. Como não há nenhuma opção definida, o sed simplesmente realizará uma operação em branco e imprimirá todo o conteúdo do arquivo.
Sed também aceita a saída de um comando diferente como fluxo de entrada. No próximo exemplo, envie o conteúdo do arquivo de texto GPL v3 via pipe para o sed para realizar uma operação em branco:
|
1 |
$ cat gpl-3.0.txt | sed '' |
Como Imprimir Linhas
Sem nenhuma opção fornecida, o sed imprimirá todo o conteúdo do arquivo diretamente. Em vez disso, podemos enviar explicitamente o comando de impressão para imprimir os resultados diretamente na saída padrão (STDOUT).
Para imprimir a saída, use o caractere p:
|
1 |
$ sed 'p' gpl-3.0.txt |
Por padrão, o sed imprime a saída na tela. Como usamos especificamente o comando de impressão, o sed imprimirá cada linha duas vezes. Sed opera linha por linha. Ele lê uma linha, realiza operações específicas, a imprime e passa para a próxima linha.
Como podemos ver, cada linha é impressa duas vezes. Se o resultado for confuso assim, podemos limpá-lo usando a opção -n. Ela suprime a função de impressão automática. Como estamos enviando o comando de impressão, não precisamos da função padrão de impressão de saída ativada:
|
1 |
$ sed -n 'p' gpl-3.0.txt |
Classes de Caracteres Regex
Em expressões regulares, existem várias classes de caracteres. Cada uma dessas classes possui um intervalo. Muitas classes também possuem múltiplas expressões. A maioria das classes são intervalos de caracteres:
-
- [a-z]: Caractere minúsculo
-
- [A-Z]: Caractere maiúsculo
-
- [0-9]: Dígitos
-
- [a-zA-z]: Alfabeto
-
- [a-zA-z0-9]: Qualquer caractere alfanumérico
Essas classes de caracteres também possuem notações diferentes:
-
- [:lower:]: Caractere minúsculo
-
- [:upper:]: Caractere maiúsculo
-
- [:digit:]: Dígitos
-
- [:alpha:]: Alfabeto
-
- [:alphanum:]: Caractere alfanumérico
Por exemplo, o seguinte comando imprimirá todas as linhas que contêm pelo menos um dígito:
|
1 |
$ sed -n 's/[[:digit:]]/&/p' gpl-3.0.txt |
Intervalos de Endereço
Podemos especificar a parte específica do fluxo de texto com a qual trabalhar. Pode ser a localização estática de uma linha ou um intervalo de linhas. No primeiro exemplo, imprimiremos a linha 5 do arquivo de texto GPL v3:
|
1 |
$ sed -n '5p' gpl-3.0.txt |
Em vez de uma única linha, também podemos especificar um intervalo de linhas para trabalhar. Aqui, definimos o intervalo de endereços da linha 5 à linha 9 (total de 5 linhas) no qual o sed irá trabalhar:
|
1 |
$ sed -n '5,9p' gpl-3.0.txt |
Também existem maneiras diferentes de especificar o endereço da linha. Em vez de determinarmos os números das linhas nós mesmos, podemos reorganizar o exemplo anterior para que o sed comece a partir da linha 5 e opere nas próximas 5 linhas:
|
1 |
$ sed -n '5,+5p' gpl-3.0.txt |
Outra maneira de especificar linhas é usando intervalos. No próximo exemplo, o sed começará a partir da linha 1 e operará em linhas alternadas:
|
1 |
$ sed -n '1~2p' gpl-3.0.txt |
Exclusão de Texto
Até agora, trabalhamos na impressão de linhas de texto de destino. Em vez de imprimir, podemos remover as linhas da saída. No exemplo a seguir, removeremos várias linhas do início. Aqui, não precisamos usar a opção -n porque queremos que o sed imprima tudo o que não for excluído. Para a exclusão de linhas, usaremos a opção d:
|
1 |
$ sed '1~2d' gpl-3.0.txt |
Note que o arquivo de origem ainda está intacto. O Sed está apenas realizando a exclusão de linhas durante a saída. Se desejar, você pode salvar a saída do sed em um arquivo. Você pode sobrescrever o arquivo original ou salvá-lo como um arquivo diferente:
|
1 |
$ sed '1~2d' gpl-3.0.txt > gpl-3.0.modified.txt |
Em vez de gravar manualmente a saída em um arquivo, o sed pode realizar uma edição local no arquivo original. Em resumo, o sed editará o arquivo original e gravará todas as alterações feitas. Este método sobrescreverá o arquivo original, por isso deve ser usado com cuidado:
|
1 |
$ sed -i '1~2d' gpl-3.0.txt |
Como a edição local é perigosa, o sed vem com o recurso de backup. Ao realizar edições locais, use -i.bak em vez de -i para fazer um backup antes de editar. O Sed criará o arquivo de backup com a extensão .bak:
|
1 |
$ sed -i.bak '1~2d' gpl-3.0.txt |
Substituição de Texto
Esta é, de longe, uma das implementações mais comuns do sed. Ele pesquisa por um padrão de texto e substitui o padrão por um texto fornecido. Aqui, o padrão de texto é descrito em expressões regulares (regex, para abreviar). Para saber mais sobre o uso de regex, siga este tutorial que descreve como usar o Grep com regex para pesquisar padrões de texto em arquivos.
Aqui está um exemplo da substituição de texto mais básica usando regex:
|
1 |
$ 's/<search_pattern>/<replacement>' |
Aqui, s é o comando para substituição. As barras são delimitadores para o padrão e a substituição. Vamos colocá-lo em ação:
|
1 |
$ echo "hello world" | sed 's/hello/HELLO/' |
O próximo exemplo demonstrará o uso do sublinhado (_). Aqui, os sublinhados atuarão como delimitadores:
|
1 |
$ echo http://example.com/index.html | sed 's_com/index_net/home_' |
Aqui, estamos pesquisando por com/index para alterar por net/home. Observe o posicionamento dos sublinhados, pois eles são cruciais. Por exemplo, se faltar o último sublinhado, o sed retornará um erro:
|
1 |
$ echo "http://www.example.com/index.html" | sed 's_com/index_net/home' |
Precisamos de um arquivo fictício para praticar algumas substituições. Aqui, tenho uma versão cortada do arquivo de texto GPL v3:
|
1 |
$ cat gpl-3.0.cropped.txt |
Vamos realizar algumas substituições básicas de texto:
|
1 |
$ cat gpl-3.0.cropped.txt | sed 's/GNU/GNU is Not Unix/' |
Dê uma olhada no próximo exemplo. Queremos alterar todas as instâncias de the para THE :
|
1 |
$ echo "the the quick brown fox jumps over the lazy dog" | sed 's/the/THE/' |
Notou algo? O Sed não alterou todas as instâncias de the. Na verdade, foi apenas a primeira instância. O que está acontecendo? Este é o comportamento padrão da opção s. Ela corresponde apenas à primeira instância de uma determinada linha e passa para a próxima. Para garantir que o sed verifique a linha inteira em busca do padrão de pesquisa, precisamos usar uma flag opcional g. Vamos corrigir o comando:
|
1 |
$ echo "the the quick brown fox jumps over the lazy dog" | sed 's/the/THE/g' |
Agora está funcionando como esperado. Outra maneira interessante de usar o comando é especificar o número de instâncias a serem alteradas. No exemplo anterior, havia 3 instâncias de the, certo? Que tal especificarmos para alterar apenas a 3ª instância? A alteração ocorrerá na flag opcional:
|
1 |
$ echo "a a rápida raposa marrom salta sobre o cão preguiçoso" | sed 's/the/THE/3' |
Se você estiver trabalhando com um arquivo de texto grande, pode ajudar se sed imprimisse apenas as linhas onde as substituições ocorreram. Para conseguir isso, precisamos adicionar outra flag adicional p:
|
1 |
$ sed -n 's/GNU/GNU is Not Unix/gp' gpl-3.0.txt |
Diferenciação de Maiúsculas e Minúsculas
Por padrão, todas as sed operações diferenciam maiúsculas de minúsculas. O comando a seguir demonstrará o comportamento padrão de diferenciação de maiúsculas e minúsculas:
|
1 |
$ echo "HELLO WORLD" | sed 's/hello/hElLo/' |
Devido à incompatibilidade de maiúsculas e minúsculas, não há alteração. Em tal situação, podemos dizer ao sed para desativar a diferenciação de maiúsculas e minúsculas. Para fazer isso, adicione a flag opcional i:
|
1 |
$ echo "HELLO WORLD" | sed 's/hello/hElLo/i' |
Como Substituir e Referenciar Textos
O poder do sed está principalmente em sua capacidade de usar expressões regulares. Com padrões regex mais avançados e complexos, podemos realizar muito mais. Por exemplo, podemos substituir o texto do início de um arquivo até um determinado local. Dê uma olhada na seguinte expressão:
|
1 |
$ sed 's/^.*GNU/GNU_replaced/' gpl-3.0.txt |
Aqui, o caractere circunflexo (^) denota o início da linha. O operador que corresponde a qualquer caractere é representado usando o ponto final (.). O asterisco (*) é a expressão curinga, correspondendo desde o início da linha até GNU.
Outro truque interessante é usar o & símbolo. Podemos usá-lo para destacar as áreas que o sed encontra o padrão de busca:
|
1 |
$ sed 's/^.*GNU/(&)/' gpl-3.0.txt |
Considerações Finais
Neste tutorial, exploramos os conceitos básicos do comando sed . Aprendemos como imprimir linhas específicas, buscar textos, excluir e substituir textos, sobrescrever textos e usar expressões regulares. Um comando sed construído corretamente pode transformar drasticamente um documento de texto. Agora você pode manipular texto com sucesso no Linux com a ajuda do sed.
Boa computação!









Comentários
Nenhum comentário ainda. Seja o primeiro.