Como usar o comando sed no Linux
Pode parecer loucura, mas o Linux sed
command é um editor de texto sem interface. Você pode usá-lo na linha de comando para manipular texto em arquivos e fluxos. Mostraremos como aproveitar seu poder.
O poder do sed
O sed
O comando é um pouco como o xadrez: leva uma hora para aprender o básico e uma vida inteira para dominá-lo (ou, pelo menos, muita prática). Mostraremos uma seleção de estratégias iniciais em cada uma das principais categorias de sed
funcionalidade.
sed
é um editor de fluxo que funciona com entrada canalizada ou arquivos de texto. Ele não tem uma interface de editor de texto interativa, no entanto. Em vez disso, você fornece instruções para que ele siga à medida que avança no texto. Tudo isso funciona no Bash e em outros shells de linha de comando.
Com sed
você pode fazer o seguinte:
- Selecionar texto
- Texto substituto
- Adicionar linhas ao texto
- Excluir linhas do texto
- Modificar (ou preservar) um arquivo original
Estruturamos nossos exemplos para apresentar e demonstrar conceitos, não para produzir o mais conciso (e menos acessível) sed
comandos. No entanto, as funcionalidades de correspondência de padrões e seleção de texto de sed
dependem fortemente de expressões regulares (regexes). Você vai precisar de alguma familiaridade com eles para obter o melhor sed
.
RELACIONADO:Como usar expressões regulares (regexes) no Linux
Um Exemplo Simples
Primeiro, vamos usar eco
enviar algum texto para sed
através de um cano, e tem sed
substitua uma parte do texto. Para fazer isso, digitamos o seguinte:
echo howtogonk | sed 's / gonk / geek /'
O eco
comando envia “howtogonk” para sed
, e nossa regra de substituição simples (o “s” significa substituição) é aplicada.sed
procura no texto de entrada uma ocorrência da primeira string e substituirá quaisquer correspondências pela segunda.
A string “gonk” é substituída por “geek” e a nova string é impressa na janela do terminal.
As substituições são provavelmente o uso mais comum de sed
. Antes de nos aprofundarmos nas substituições, no entanto, precisamos saber como selecionar e combinar o texto.
Selecionando Texto
Vamos precisar de um arquivo de texto para nossos exemplos. Usaremos um que contém uma seleção de versos do poema épico de Samuel Taylor Coleridge "The Rime of the Ancient Mariner".
Nós digitamos o seguinte para dar uma olhada com menos
:
menos coleridge.txt
Para selecionar algumas linhas do arquivo, fornecemos as linhas inicial e final do intervalo que desejamos selecionar. Um único número seleciona essa linha.
Para extrair as linhas um a quatro, digitamos este comando:
sed -n '1,4p' coleridge.txt
Observe a vírgula entre 1
e 4
. O p
significa “imprimir linhas correspondentes”. Por padrão,sed
imprime todas as linhas. Veríamos todo o texto no arquivo com as linhas correspondentes impressas duas vezes. Para evitar isso, usaremos o -n
(silencioso) opção para suprimir o texto sem correspondência.
Alteramos os números das linhas para que possamos selecionar um versículo diferente, conforme mostrado abaixo:
sed -n '6,9p' coleridge.txt
Podemos usar o -e
(expressão) opção para fazer várias seleções. Com duas expressões, podemos selecionar dois versos, assim:
sed -n -e '1,4p' -e '31, 34p 'coleridge.txt
Se reduzirmos o primeiro número na segunda expressão, podemos inserir um espaço em branco entre os dois versos. Nós digitamos o seguinte:
sed -n -e '1,4p' -e '30, 34p 'coleridge.txt
Também podemos escolher uma linha de partida e contar sed
para percorrer o arquivo e imprimir linhas alternativas, a cada cinco linhas, ou para pular qualquer número de linhas. O comando é semelhante aos que usamos acima para selecionar um intervalo. Desta vez, no entanto, usaremos um til (~
) em vez de uma vírgula para separar os números.
O primeiro número indica a linha de partida. O segundo número diz sed
quais linhas após a linha de partida queremos ver. O número 2 significa cada segunda linha, 3 significa cada terceira linha e assim por diante.
Nós digitamos o seguinte:
sed -n '1 ~ 2p' coleridge.txt
Você nem sempre saberá onde o texto que está procurando está localizado no arquivo, o que significa que os números das linhas nem sempre ajudam muito. No entanto, você também pode usar sed
para selecionar linhas que contêm padrões de texto correspondentes. Por exemplo, vamos extrair todas as linhas que começam com "E".
O acento circunflexo (^
) representa o início da linha. Colocaremos nosso termo de pesquisa entre barras (/
) Também incluímos um espaço após "E" para que palavras como "Android" não sejam incluídas no resultado.
Leitura sed
scripts podem ser um pouco difíceis no início. O / p
significa “imprimir”, assim como nos comandos que usamos acima. No comando a seguir, porém, uma barra o precede:
sed -n '/ ^ E / p' coleridge.txt
Três linhas que começam com “E” são extraídas do arquivo e exibidas para nós.
Fazendo substituições
Em nosso primeiro exemplo, mostramos o seguinte formato básico para um sed
substituição:
echo howtogonk | sed 's / gonk / geek /'
O s
conta sed
esta é uma substituição. A primeira string é o padrão de pesquisa e a segunda é o texto com o qual queremos substituir o texto correspondente. Claro, como em todas as coisas do Linux, o diabo está nos detalhes.
Digitamos o seguinte para alterar todas as ocorrências de "dia" para "semana" e dar ao marinheiro e ao albatroz mais tempo para se relacionarem:
sed -n 's / dia / semana / p' coleridge.txt
Na primeira linha, apenas a segunda ocorrência de “dia” é alterada. Isto é porque sed
pára após a primeira correspondência por linha. Temos que adicionar um “g” no final da expressão, conforme mostrado abaixo, para realizar uma pesquisa global para que todas as correspondências em cada linha sejam processadas:
sed -n 's / dia / semana / gp' coleridge.txt
Isso corresponde a três dos quatro na primeira linha. Porque a primeira palavra é "Dia" e sed
diferencia maiúsculas de minúsculas, não considera essa instância igual a "dia".
Nós digitamos o seguinte, adicionando um eu
ao comando no final da expressão para indicar não diferenciação de maiúsculas e minúsculas:
sed -n 's / dia / semana / gip' coleridge.txt
Isso funciona, mas você nem sempre deseja ativar a não diferenciação de maiúsculas e minúsculas para tudo. Nesses casos, você pode usar um grupo regex para adicionar insensibilidade a casos específicos de padrão.
Por exemplo, se colocarmos os caracteres entre colchetes ([]
), eles são interpretados como “qualquer caractere desta lista de caracteres”.
Digitamos o seguinte e incluímos “D” e “d” no grupo, para garantir que corresponda a “Dia” e “dia”:
sed -n 's / [Dd] ay / semana / gp' coleridge.txt
Também podemos restringir as substituições a seções do arquivo. Digamos que nosso arquivo contenha espaçamentos estranhos no primeiro verso. Podemos usar o seguinte comando familiar para ver o primeiro versículo:
sed -n '1,4p' coleridge.txt
Vamos procurar dois espaços e substituí-los por um. Faremos isso globalmente para que a ação se repita em toda a linha. Para ser claro, o padrão de pesquisa é espaço, espaço asterisco (*
), e a string de substituição é um único espaço. O 1,4
restringe a substituição às primeiras quatro linhas do arquivo.
Colocamos tudo isso junto no seguinte comando:
sed -n '1,4 s / * / / gp' coleridge.txt
Isso funciona muito bem! O padrão de pesquisa é o que é importante aqui. O asterisco (*
) representa zero ou mais do caractere anterior, que é um espaço. Assim, o padrão de pesquisa está procurando cadeias de um espaço ou mais.
Se substituirmos um único espaço por qualquer sequência de vários espaços, retornaremos o arquivo ao espaçamento regular, com um único espaço entre cada palavra. Isso também substituirá um único espaço por um único espaço em alguns casos, mas isso não afetará nada adversamente - ainda obteremos o resultado desejado.
Se digitarmos o seguinte e reduzirmos o padrão de pesquisa a um único espaço, você verá imediatamente porque temos que incluir dois espaços:
sed -n '1,4 s / * / / gp' coleridge.txt
Como o asterisco corresponde a zero ou mais do caractere anterior, ele vê cada caractere que não é um espaço como um "espaço zero" e aplica a substituição a ele.
No entanto, se incluirmos dois espaços no padrão de pesquisa,sed
deve encontrar pelo menos um caractere de espaço antes de aplicar a substituição. Isso garante que os caracteres sem espaço permanecerão intocados.
Nós digitamos o seguinte, usando o -e
(expressão) que usamos anteriormente, o que nos permite fazer duas ou mais substituições simultaneamente:
sed -n -e 's / motion / flutter / gip' -e 's / ocean / gutter / gip' coleridge.txt
Podemos obter o mesmo resultado se usarmos um ponto e vírgula (;
) para separar as duas expressões, assim:
sed -n 's / motion / flutter / gip; s / ocean / gutter / gip' coleridge.txt
Quando trocamos “dia” por “semana” no comando a seguir, a instância de “dia” na expressão “bem por dia” também foi trocada:
sed -n 's / [Dd] ay / semana / gp' coleridge.txt
Para evitar isso, só podemos tentar substituições em linhas que correspondam a outro padrão. Se modificarmos o comando para ter um padrão de pesquisa no início, consideraremos operar apenas em linhas que correspondam a esse padrão.
Nós digitamos o seguinte para tornar nosso padrão de correspondência a palavra “depois”:
sed -n '/ after / s / [Dd] ay / week / gp' coleridge.txt
Isso nos dá a resposta que desejamos.
Substituições mais complexas
Vamos dar um tempo ao Coleridge e usar sed
para extrair nomes do etc / passwd
Arquivo.
Existem maneiras mais curtas de fazer isso (mais sobre isso mais tarde), mas usaremos a maneira mais longa aqui para demonstrar outro conceito. Cada item correspondido em um padrão de pesquisa (chamado de subexpressões) pode ser numerado (até no máximo nove itens). Você pode então usar esses números em seused
comandos para fazer referência a subexpressões específicas.
Você deve colocar a subexpressão entre parênteses [()
] para que isso funcione. Os parênteses também devem ser precedidos por uma barra invertida (\
) para evitar que sejam tratados como um personagem normal.
Para fazer isso, você digitaria o seguinte:
sed 's / \ ([^:] * \). * / \ 1 /' / etc / passwd
Vamos decompô-lo:
sed 's /
: Osed
comando e o início da expressão de substituição.\(
: O parêntese de abertura [(
] envolvendo a subexpressão, precedida por uma barra invertida (\
).[^:]*
: A primeira subexpressão do termo de pesquisa contém um grupo entre colchetes. O acento circunflexo (^
) significa "não" quando usado em um grupo. Um grupo significa qualquer caractere que não seja dois pontos (:
) serão aceitos como uma correspondência.\)
: O parêntese de fechamento [)
] com uma barra invertida precedente (\
)..*
: Esta segunda subexpressão de pesquisa significa “qualquer caractere e qualquer número deles”./\1
: A porção de substituição da expressão contém1
precedido por uma barra invertida (\
) Isso representa o texto que corresponde à primeira subexpressão./'
: A barra de fechamento (/
) e aspas simples ('
) encerrar osed
comando.
O que tudo isso significa é que vamos procurar por qualquer sequência de caracteres que não contenha dois pontos (:
), que será a primeira instância do texto correspondente. Em seguida, estamos procurando por qualquer outra coisa nessa linha, que será a segunda instância do texto correspondente. Vamos substituir a linha inteira pelo texto que correspondeu à primeira subexpressão.
Cada linha no / etc / passwd
arquivo começa com um nome de usuário terminado por dois pontos. Combinamos tudo até o primeiro dois pontos e, em seguida, substituímos esse valor por toda a linha. Portanto, isolamos os nomes de usuário.
A seguir, colocaremos a segunda subexpressão entre parênteses [()
] para que possamos referenciá-lo por número também. Também substituiremos \1
com \2
. Nosso comando irá agora substituir a linha inteira por tudo desde os primeiros dois pontos (:
) até o final da linha.
Nós digitamos o seguinte:
sed 's / \ ([^:] * \) \ (. * \) / \ 2 /' / etc / passwd
Essas pequenas alterações invertem o significado do comando e obtemos tudo, exceto os nomes de usuário.
Agora, vamos dar uma olhada na maneira rápida e fácil de fazer isso.
Nosso termo de pesquisa vem do primeiro dois pontos (:
) até o final da linha. Porque nossa expressão de substituição está vazia (//
), não substituiremos o texto correspondente por nada.
Então, digitamos o seguinte, cortando tudo desde o primeiro dois pontos (:
) ao final da linha, deixando apenas os nomes de usuário:
sed 's /:.*// "/ etc / passwd
Vejamos um exemplo em que referenciamos a primeira e a segunda correspondências no mesmo comando.
Temos um arquivo de vírgulas (,
) separando nomes e sobrenomes. Queremos listá-los como "sobrenome, nome". Podemos usargato
, conforme mostrado abaixo, para ver o que há no arquivo:
cat geeks.txt
Gosto muito de sed
comandos, este próximo pode parecer impenetrável à primeira vista:
sed 's / ^ \ (. * \), \ (. * \) $ / \ 2, \ 1 / g' geeks.txt
Este é um comando de substituição como os outros que usamos, e o padrão de pesquisa é bastante fácil. Vamos decompô-lo abaixo:
sed 's /
: O comando de substituição normal.^
: Porque o acento circunflexo não está em um grupo ([]
), significa "O início da linha".\(.*\),
: A primeira subexpressão é qualquer número de quaisquer caracteres. Está entre parênteses [()
], cada um precedido por uma barra invertida (\
) para que possamos referenciá-lo por número. Todo o nosso padrão de pesquisa até agora se traduz como pesquisa do início da linha até a primeira vírgula (,
) para qualquer número de quaisquer caracteres.\(.*\)
: A próxima subexpressão é (novamente) qualquer número de qualquer caractere. Também está entre parênteses [()
], ambos precedidos por uma barra invertida (\
) para que possamos fazer referência ao texto correspondente por número.$/
: O cifrão ($
) representa o fim da linha e permitirá que nossa pesquisa continue até o fim da linha. Usamos isso simplesmente para apresentar o cifrão. Nós realmente não precisamos dele aqui, como o asterisco (*
) iria para o fim da linha neste cenário. A barra (/
) completa a seção de padrão de pesquisa.\ 2, \ 1 / g '
: Como colocamos nossas duas subexpressões entre parênteses, podemos nos referir a ambas por seus números. Porque queremos inverter a ordem, nós os digitamos comosegunda partida, primeira partida
. Os números devem ser precedidos por uma barra invertida (\
)./ g
: Isso permite que nosso comando funcione globalmente em cada linha.geeks.txt
: O arquivo em que estamos trabalhando.
Você também pode usar o comando Cortar (c
) para substituir linhas inteiras que correspondem ao seu padrão de pesquisa. Digitamos o seguinte para pesquisar uma linha com a palavra “pescoço” e a substituímos por uma nova string de texto:
sed '/ neck / c Em volta do meu pulso foi amarrado' coleridge.txt
Nossa nova linha agora aparece na parte inferior de nosso extrato.
Inserindo Linhas e Texto
Também podemos inserir novas linhas e texto em nosso arquivo. Para inserir novas linhas após as correspondentes, usaremos o comando Append (uma
).
Este é o arquivo com o qual vamos trabalhar:
cat geeks.txt
Numeramos as linhas para tornar isso um pouco mais fácil de seguir.
Digitamos o seguinte para pesquisar linhas que contenham a palavra “Ele” e inserimos uma nova linha abaixo delas:
sed '/ He / a -> Inserido!' geeks.txt
Nós digitamos o seguinte e incluímos o Comando Inserir (eu
) para inserir a nova linha acima daquelas que contêm o texto correspondente:
sed '/ He / i -> Inserido!' geeks.txt
Podemos usar o e comercial (&
), que representa o texto original correspondente, para adicionar um novo texto a uma linha correspondente. \1
, \2
e assim por diante, representam subexpressões correspondentes.
Para adicionar texto ao início de uma linha, usaremos um comando de substituição que corresponde a tudo na linha, combinado com uma cláusula de substituição que combina nosso novo texto com a linha original.
Para fazer tudo isso, digitamos o seguinte:
sed 's /.*/--> Inserido & /' geeks.txt
Nós digitamos o seguinte, incluindo o G
comando, que adicionará uma linha em branco entre cada linha:
sed 'G' geeks.txt
Se você quiser adicionar duas ou mais linhas em branco, você pode usar G; G
, G; G; G
, e assim por diante.
Excluindo linhas
O comando Delete (d
) exclui linhas que correspondem a um padrão de pesquisa ou aquelas especificadas com números de linha ou intervalos.
Por exemplo, para excluir a terceira linha, digitaríamos o seguinte:
sed '3d' geeks.txt
Para excluir o intervalo das linhas quatro a cinco, digitaríamos o seguinte:
sed '4,5d' geeks.txt
Para excluir linhas fora de um intervalo, usamos um ponto de exclamação (!
), como mostrado abaixo:
sed '6,7! d' geeks.txt
Salvando suas alterações
Até agora, todos os nossos resultados foram impressos na janela do terminal, mas ainda não os salvamos em nenhum lugar. Para torná-los permanentes, você pode gravar suas alterações no arquivo original ou redirecioná-las para um novo.
Substituir seu arquivo original requer algum cuidado. Se seu sed
estiver errado, você pode fazer algumas alterações no arquivo original que são difíceis de desfazer.
Para um pouco de paz de espírito, sed
pode criar um backup do arquivo original antes de executar seu comando.
Você pode usar a opção No local (-eu
) contarsed
para gravar as alterações no arquivo original, mas se você adicionar uma extensão de arquivo a ele, sed
fará o backup do arquivo original em um novo. Ele terá o mesmo nome do arquivo original, mas com uma nova extensão de arquivo.
Para demonstrar, vamos pesquisar todas as linhas que contenham a palavra “Ele” e excluí-las. Também faremos backup de nosso arquivo original em um novo usando a extensão BAK.
Para fazer tudo isso, digitamos o seguinte:
sed -i'.bak '' /^.*He.*$/d 'geeks.txt
Digitamos o seguinte para garantir que nosso arquivo de backup não seja alterado:
cat geeks.txt.bak
Também podemos digitar o seguinte para redirecionar a saída para um novo arquivo e obter um resultado semelhante:
sed -i'.bak '' /^.*He.*$/d 'geeks.txt> new_geeks.txt
Nós usamos gato
para confirmar que as alterações foram gravadas no novo arquivo, conforme mostrado abaixo:
cat new_geeks.txt
Tendo sed tudo isso
Como você provavelmente notou, mesmo esta introdução rápida sobre sed
é bastante longo. Esse comando é muito complexo e você ainda pode fazer mais com ele.
Esperançosamente, porém, esses conceitos básicos forneceram uma base sólida sobre a qual você pode construir à medida que aprende mais.