Esta resposta é um trabalho em progresso - falta mais exemplos sobre o comando susbstitute
O que é sed
?
sed
= Stream EDitor
A descrição na página de manual para relatórios GNU sed
4.2.2:
Sed é um editor de fluxo. 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 permite edições com script (como ed), o sed funciona fazendo apenas uma passagem sobre a (s) entrada (s) e, consequentemente, é 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
page no gnu.org :
sed (editor de fluxo) não é um editor de texto interativo. Em vez disso, ele é usado para filtrar texto, isto é, recebe entrada de texto, executa alguma operação (ou conjunto de operações) e exibe o texto modificado. O sed é normalmente usado para extrair parte de um arquivo usando correspondência de padrões ou substituindo várias ocorrências de uma string dentro de um arquivo.
Para que sed
é usado?
Ele pode ser usado para realizar modificações complexas em fluxos de dados (geralmente texto, mas também pode ser usado para modificar dados binários).
Entre os casos mais comuns de uso, há:
- Impressão / exclusão seletiva de linhas de um arquivo de texto usando expressões regulares básicas / estendidas
- Substituindo strings globalmente em um arquivo de texto usando expressões regulares básicas / estendidas
- Substituindo strings seletivamente em um arquivo de texto usando expressões regulares básicas / estendidas
Estes 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 comando durante sua invocação, ou de stdin
se nenhum nome de arquivo for especificado.
Invocação mínima usando um arquivo armazenado no sistema de arquivos:
sed '' file
Invocação 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; ele lê uma linha, remove a nova linha 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 comando p
ou d
é especificado *, sed
sempre imprime o conteúdo atual do espaço padrão seguido por uma nova linha em 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 evitar isso, é possível invocar sed
junto com a opção -n
:
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 todo o arquivo de entrada ou processar apenas as 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.
Possíveis combinações de endereços são:
-
<N>
(onde <N>
é um número): os seguintes comandos / comandos serão executados apenas no número de linha <N>
;
-
<N>,<M>
(onde <N>
e <M>
são dois números, <N>
& gt; <M>
): os seguintes comandos / comandos serão executados em linhas que vão do número de linha <N>
ao número de 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 expressões regulares básicas ou estendidas): os seguintes comandos / comandos serão executados em linhas que vão desde a primeira linha contendo uma ocorrência de <pattern1>
até a próxima linha contendo uma ocorrência de <pattern2>
, várias vezes no caso de várias ordenações <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 vão do número de linha <N>
até a primeira linha contendo 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 é preguiçoso 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 somente linhas nas quais uma substituição foi executada, é necessário invocar sed
junto com a opção -n
para evitar que as linhas que correspondem ao critério sejam impressas duas vezes (isso ocorre apenas ao imprimir intervalos de linhas) e para evitar que as linhas que não correspondam ao critério sejam impressas 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 que correspondem ao endereço / intervalo de endereços especificado;
-
d
: exclui linhas que correspondem 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
Imprimindo / excluindo linhas especificando endereços numéricos:
Arquivo de amostra:
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>
to <M>
inclusive:
sed -n '<N>,<M>p' file
user@debian ~ % sed -n '2,4p' file
line2
line3
line4
- Excluindo a linha
<N>
to <M>
inclusive:
sed '<N>,<M>d' file
user@debian ~ % sed '2,4d' file
line1
line5
Imprimindo / excluindo linhas especificando padrões:
Arquivo de amostra:
First line
Start printing / deleting here
Random line
Random line
Random line
Stop printing / deleting here
Last line
- Linhas de impressão correspondentes a
<pattern>
:
sed -n '/<pattern>/p' file
user@debian ~ % sed -n '/print/p' file
Start printing / deleting here
Stop printing / deleting here
- Excluindo linhas correspondentes a
<pattern>
:
sed '/<pattern>/d' file
user@debian ~ % sed '/print/d' file
First line
Random line
Random line
Random line
Last line
- Linhas de impressão da linha correspondente a
<pattern1>
à linha correspondente a <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 que corresponde a
<pattern1>
à linha correspondente a <pattern2>
inclusive:
sed '/<pattern1>/,/<pattern2>/d' file
user@debian ~ % sed '/Start/,/Stop/d' file
First line
Last line
Comando: substituto
O comando usado para realizar uma substituição em uma seleção é:
-
s
: substitui as linhas que correspondem 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 comando s
é:
s/<pattern>/<replacement_string>/<pattern_flags>
Barras são "delimitadores"; eles são usados para delimitar as seções <pattern>
, <replacement_string>
e <pattern_flags>
;
O delimitador é sempre o caractere imediatamente após o comando s
; 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 sequências específicas de sed
com um significado especial; <pattern_flags>
é uma lista de sinalizadores que modificam o comportamento de <pattern>
.
Sequências específicas de sed
mais comuns com um significado especial:
-
&
: backreference substituído pela string correspondida por <pattern>
;
-
\<N>
(onde <N>
é um número): backreference substituída pelo grupo <N>
capturado em <pattern>
;
Sinalizadores mais comuns:
-
g
: força <pattern>
a corresponder globalmente, por exemplovárias vezes em cada linha;
-
i
: força <pattern>
a corresponder insensivelmente a maiúsculas e minúsculas;
-
p
: imprime linhas nas quais uma substituição foi executada novamente (útil ao usar a opção -n
na invocação de sed
para imprimir apenas as linhas nas quais uma substituição foi executada);
Exemplos: substitua
Arquivo de amostra:
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>
por <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>
por <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 as linhas que começam com
<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 substituindo 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