Esta resposta é um trabalho em andamento - faltam mais exemplos sobre o comando susbstitute
O que é sed
?
sed
= Stream EDitor
A descrição na página de manual dos sed
relatórios GNU 4.2.2:
Sed é um editor de stream. Um editor de fluxo é usado para executar transformações básicas de texto em um fluxo de entrada (um arquivo ou entrada de um pipeline). Embora, de certa forma, semelhante a um editor que permita edições com script (como ed), o sed funcione fazendo apenas uma passagem sobre a (s) entrada (s) e, consequentemente, seja mais eficiente. Mas é a capacidade do sed de filtrar texto em um pipeline que o distingue particularmente de outros tipos de editores.
A descrição na página GNU sed
em gnu.org relata:
sed (editor de stream) não é um editor de texto interativo. Em vez disso, é usado para filtrar o texto, ou seja, recebe a entrada de texto, realiza alguma operação (ou conjunto de operações) e gera o texto modificado. sed é normalmente usado para extrair parte de um arquivo usando a correspondência de padrões ou a substituição de várias ocorrências de uma string em um arquivo.
Para que é sed
utilizado?
Ele pode ser usado para executar modificações complexas nos fluxos de dados (geralmente texto, mas também pode ser usado para modificar dados binários).
Entre os casos mais comuns de uso, existem:
- Impressão / exclusão seletiva de linhas de um arquivo de texto usando expressões regulares básicas / estendidas
- Substituindo globalmente cadeias de caracteres em um arquivo de texto usando expressões regulares básicas / estendidas
- Substituindo seletivamente cadeias de caracteres em um arquivo de texto usando expressões regulares básicas / estendidas
Esses são os casos de uso abordados nesta resposta.
Uso
sed
lê a entrada de um arquivo armazenado no sistema de arquivos se um nome de arquivo for especificado nos argumentos da linha de comandos durante sua chamada ou a partir de stdin
se nenhum nome de arquivo for especificado.
Chamada mínima usando um arquivo armazenado no sistema de arquivos:
sed '' file
Chamada mínima usando stdin
:
# herestring
<<<'Hello, World!' sed ''
# heredoc
<<'EOF' sed ''
heredoc> Hello, World!
heredoc> EOF
# file
<'file' sed ''
# pipe
echo 'Hello, World!' | sed ''
Olá Mundo!
sed
por padrão, lê o arquivo de entrada linha por linha; lê uma linha, remove a nova linha à direita da linha e coloca a linha processada em um "espaço padrão"; finalmente, ele executa os comandos listados no conteúdo atual do espaço padrão e lê uma nova linha do arquivo de entrada.
Quando nenhum comando é especificado ou quando um p
ou um d
comando é especificado *, sed
sempre será impresso o conteúdo atual do espaço do padrão seguido por uma nova linha a cada iteração, independentemente:
user@debian ~ % sed '' file
Hello, world! # no command but the lines are printed
user@debian ~ % sed 'p' file
Hello, World!
Hello, World! # the p command prints the lines already printed
user@debian ~ % sed 'd' file
user@debian ~ % # the d command deletes the lines that would be printed
Para impedir que este possa ser chamado sed
junto com o -n
comutador:
user@debian ~ % sed -n '' file
user@debian ~ % sed -n 'p' file
Hello, World!
user@debian ~ % sed -n 'd' file
user@debian ~ %
* Falando apenas para os comandos p
, d
e s
, que são os comandos abordados nesta resposta.
Seleção de linhas
sed
pode processar o arquivo de entrada inteiro ou processar apenas linhas selecionadas do arquivo de entrada; a seleção das linhas do arquivo de entrada a ser processado é feita especificando "endereços"; um endereço pode ser (entre outras coisas) um número de linha ou um padrão; intervalos de linhas podem ser selecionados especificando intervalos de endereços.
As combinações possíveis de endereços são:
<N>
(onde <N>
está um número): os seguintes comandos / comandos serão executados apenas no número da linha <N>
;
<N>,<M>
(onde <N>
e <M>
são dois números, <N>
> <M>
): os seguintes comandos / comandos serão executados em linhas que variam do número da linha <N>
ao número da linha <M>
inclusive;
/<pattern>/
(onde <pattern>
é uma expressão regular básica ou estendida): os seguintes comandos / comandos serão executados apenas nas linhas que contêm uma ocorrência de <pattern>
;
/<pattern1>/,/<pattern2>/
(Onde <pattern1>
e <pattern2>
são básicos ou expressões regulares estendidas): a sequência de comando / comandos será executado em linhas que vão desde a primeira linha contendo uma ocorrência de <pattern1>
para a linha seguinte contendo uma ocorrência de <pattern2>
, várias vezes, no caso de múltiplos ordenados <pattern1>
- <pattern2>
ocorrências;
<N>,/pattern/
(Onde <N>
é um número e <pattern>
é uma expressão regular básica ou estendida): os seguintes comandos / comandos serão executados em linhas que variam do número da linha <N>
à primeira linha que contém uma ocorrência de <pattern>
;
/pattern/,<N>
(Onde <pattern>
é uma expressão regular básica ou estendida e <N>
é um número): os seguintes comandos / comandos serão executados em linhas que vão da primeira linha contendo uma ocorrência de <pattern>
até o número da linha <N>
;
A seleção realizada para imprimir, excluir ou executar substituições em intervalos de linhas sempre incluirá as linhas correspondentes aos endereços especificados; além disso, a seleção realizada para imprimir, excluir ou executar substituições em intervalos de linhas usando padrões é lenta e global (ou seja, cada intervalo afetado será sempre o menor possível e vários intervalos serão afetados).
Ao imprimir intervalos de linhas ou imprimir apenas linhas nas quais uma substituição foi executada, é necessário chamar sed
junto com a -n
opção para evitar que as linhas correspondentes ao critério sejam impressas duas vezes (isso ocorre apenas ao imprimir intervalos de linhas) e em ordem para impedir que as linhas não correspondam ao critério a ser impresso independentemente.
Uma seleção de linhas a serem processadas deve ser seguida por um comando ou por vários comandos separados por ponto e vírgula agrupados usando chaves.
Comandos: imprimir, excluir
Os comandos usados para imprimir ou excluir uma seleção são, respectivamente:
p
: imprime linhas correspondentes ao endereço / intervalo de endereços especificado;
d
: exclui linhas correspondentes ao endereço / intervalo de endereços especificado;
Quando um desses comandos não é precedido por um endereço / seleção, o comando é executado globalmente, ou seja, em cada linha do arquivo de entrada.
Exemplos: imprimir, excluir
Impressão / exclusão de linhas especificando endereços numéricos:
Arquivo de exemplo:
line1
line2
line3
line4
line5
sed -n '<N>p' file
user@debian ~ % sed -n '3p' file
line3
sed '<N>d' file
user@debian ~ % sed '3d' file
line1
line2
line4
line5
- Linha de impressão
<N>
para <M>
inclusive:
sed -n '<N>,<M>p' file
user@debian ~ % sed -n '2,4p' file
line2
line3
line4
- Excluindo linha
<N>
para <M>
inclusivo:
sed '<N>,<M>d' file
user@debian ~ % sed '2,4d' file
line1
line5
Impressão / exclusão de linhas especificando padrões:
Arquivo de exemplo:
First line
Start printing / deleting here
Random line
Random line
Random line
Stop printing / deleting here
Last line
- Linhas de impressão correspondentes
<pattern>
:
sed -n '/<pattern>/p' file
user@debian ~ % sed -n '/print/p' file
Start printing / deleting here
Stop printing / deleting here
- Excluindo linhas correspondentes
<pattern>
:
sed '/<pattern>/d' file
user@debian ~ % sed '/print/d' file
First line
Random line
Random line
Random line
Last line
- Imprimir linhas da linha correspondente
<pattern1>
à linha correspondente <pattern2>
inclusive:
sed -n '/<pattern1>/,/<pattern2>/p' file
user@debian ~ % sed -n '/Start/,/Stop/p' file
Start printing / deleting here
Random line
Random line
Random line
Stop printing / deleting here
- Excluindo linhas da linha correspondente
<pattern1>
à linha correspondente <pattern2>
inclusive:
sed '/<pattern1>/,/<pattern2>/d' file
user@debian ~ % sed '/Start/,/Stop/d' file
First line
Last line
Comando: substitute
O comando usado para executar uma substituição em uma seleção é:
s
: substitui as linhas correspondentes ao endereço / intervalo de endereços especificado;
Quando este comando não é precedido por um endereço / seleção, o comando é executado globalmente, ou seja, em cada linha do arquivo de entrada.
A sintaxe do s
comando é:
s/<pattern>/<replacement_string>/<pattern_flags>
Barras são "delimitadores"; eles são usados para delimitar a <pattern>
, <replacement_string>
e <pattern_flags>
seções;
O delimitador é sempre o caractere imediatamente após o s
comando; pode ser definido para qualquer outro caractere, por exemplo |
:
s|<pattern>|<replacement_string>|<pattern_flags>
<pattern>
é uma expressão regular básica ou estendida; <replacement_string>
é uma cadeia fixa que pode incluir sed
sequências específicas com um significado especial;<pattern_flags>
é uma lista de sinalizadores que modificam o comportamento de<pattern>
.
sed
Sequências específicas mais comuns com um significado especial:
&
: referência anterior substituída pela string correspondida por <pattern>
;
\<N>
(onde <N>
está um número): referência anterior substituída pelo <N>
grupo capturado em <pattern>
;
Sinalizadores mais comuns:
g
: força <pattern>
a combinar globalmente, ou seja, várias vezes em cada linha;
i
: forças <pattern>
para combinar com maiúsculas e minúsculas;
p
: imprime linhas nas quais uma substituição foi executada mais uma vez (útil ao usar a -n
chave nosed
de imprimir para imprimir apenas as linhas nas quais uma substituição foi executada);
Exemplos: substituto
Arquivo de exemplo:
A-well-a everybody's heard about the bird
B-b-b-bird, bird, bird, b-bird's the word
A-well-a bird, bird, bird, the bird is the word
A-well-a bird, bird, bird, well the bird is the word
A-well-a bird, bird, bird, b-bird's the word
A-well-a bird, bird, bird, well the bird is the word
A-well-a bird, bird, b-bird's the word
A-well-a bird, bird, bird, b-bird's the word
A-well-a bird, bird, bird, well the bird is the word
A-well-a bird, bird, b-bird's the word
A-well-a don't you know about the bird?
Well, everybody knows that the bird is the word!
A-well-a bird, bird, b-bird's the word
A-well-a...
- Substituindo a primeira ocorrência de
<pattern>
com <replacement_string>
em cada linha:
sed 's/<pattern>/<replacement_string>/' file
user@debian ~ % sed 's/bird/birds/' file
A-well-a everybody's heard about the birds
B-b-b-birds, bird, bird, b-bird's the word
A-well-a birds, bird, bird, the bird is the word
A-well-a birds, bird, bird, well the bird is the word
A-well-a birds, bird, bird, b-bird's the word
A-well-a birds, bird, bird, well the bird is the word
A-well-a birds, bird, b-bird's the word
A-well-a birds, bird, bird, b-bird's the word
A-well-a birds, bird, bird, well the bird is the word
A-well-a birds, bird, b-bird's the word
A-well-a don't you know about the birds?
Well, everybody knows that the birds is the word!
A-well-a birds, bird, b-bird's the word
- Substituindo todas as ocorrências de
<pattern>
com <replacement_string>
em cada linha:
sed 's/<pattern>/<replacement_string>/g' file
user@debian ~ % sed 's/bird/birds/g' file
A-well-a everybody's heard about the birds
B-b-b-birds, birds, birds, b-birds's the word
A-well-a birds, birds, birds, the birds is the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, birds, b-birds's the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, b-birds's the word
A-well-a birds, birds, birds, b-birds's the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, b-birds's the word
A-well-a don't you know about the birds?
Well, everybody knows that the birds is the word!
A-well-a birds, birds, b-birds's the word
A-well-a...
- Selecionando apenas linhas iniciando
<pattern1>
e substituindo todas as ocorrências de <pattern2>
por <replacement_string>
:
sed -n '/^<pattern1>/s/<pattern2>/<replacement_string>/pg' file
user@debian ~ % sed -n '/^A/s/bird/birds/pg' file
A-well-a everybody's heard about the birds
A-well-a birds, birds, birds, the birds is the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, birds, b-birds's the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, b-birds's the word
A-well-a birds, birds, birds, b-birds's the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, b-birds's the word
A-well-a don't you know about the birds?
A-well-a birds, birds, b-birds's the word
- Selecionando apenas as linhas que terminam com
<pattern1>
e substituem todas as ocorrências de <pattern2>
por <replacement_string>
:
sed -n '/<pattern1>$/s/<pattern2>/<replacement_string>/pg' file
user@debian ~ % sed -n '/word$/s/bird/birds/pg' file
B-b-b-birds, birds, birds, b-birds's the word
A-well-a birds, birds, birds, the birds is the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, birds, b-birds's the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, b-birds's the word
A-well-a birds, birds, birds, b-birds's the word
A-well-a birds, birds, birds, well the birds is the word
A-well-a birds, birds, b-birds's the word
A-well-a birds, birds, b-birds's the word
Sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline). While in some ways similar to an editor which permits scripted edits (such as ed), sed works by making only one pass over the input(s), and is consequently more efficient. But it is sed's ability to filter text in a pipeline which particularly distinguishes it from other types of editors.