Linux alterando textos no terminal com sed sem enrolação
.
Para usar o comando sed, eu tenho um arquivo com preços de produtos.
1, Produto A, Title 545, Price $6.30
2, Produto B, Title 723, Price $7.90
3, Produto C, Title 610, Price $7.90
4, Produto A, Title 118, Price $6.30
5, Produto B, Title 482, Price $6.50
6, Produto C, Title 335, Price $6.30
7, Produto A, Title 271, Price $7.90
.
Crio o arquivo abrindo o terminal pelo menu do sistema. Executo:
1)
mkdir -v DirSed
2)
cd DirSed/
3)
echo -e '1, Produto A, Title 545, Price $6.30
2, Produto B, Title 723, Price $7.90 \n3, Produto C, Title 610, Price $7.90 \n4, Produto A, Title 118, Price $6.30 \n5, Produto B, Title 482, Price $6.50 \n6, Produto C, Title 335, Price $6.30 \n7, Produto A, Title 271, Price $7.90' > ArqProdut.txt ; cat ArqProdut.txt
.
OBS:
Quero mudar o preço dos produtos que custam 6.30 para 7.30.
.
Executo:
1) sed 's/6.30/7.30/' > ArqProdut.txt
2) cat ArqProdut.txt
.
As duas principais ferramentas para manipulação de arquivos e streams do Unix/Linux/GNU talvez sejam o "sed" e o "awk".
.
Com o SED é possível substituir e “casar” padrões, sempre por meio de Expressões Regulares.
.
O esquema SED e AWK:
O comando lê um arquivo, linha por linha, e aplica a expressão do parâmetro a cada uma delas.
.
A FÓRMULA DO SUCESSO COM SED:
.
1) sed 's/texto-a-ser-substituido/texto-novo/'
2) sed -i 's,palavra-a-ser-substituida,palavra-nova,' nome-do-arquivo.txt
.
OBS:
(a opção -i, sobrescreve o conteúdo do nome-do-arquivo.txt)
.
3) sed 's,texto-a-ser-substituido,texto-novo,' *
4) sed -i 's,texto-a-ser-substituido,texto-novo,g' *
.
OBS:
O comando acima faz a substituição de uma mesma string dentro de vários arquivos de um mesmo diretório fazendo uso do comando sed
.
5)
> nome-do-arquivo.txt
sed -i.novobkp 's,palavra-a-ser-substituida,palavra-nova,' nome-do-arquivo.txt
.
É possível filtrar a saída de outro comando, em vez de filtrar um arquivo, usando pipe "|".
.
Executo:
1)
echo "Testando o sed: Aprendo a trabalhar com sed" | sed 's/sed/awk/'
2)
echo "Testando a vida: Aprendo a trabalhar com a vida" | sed 's/vida/morte/'
3)
echo "Testando o claro: Aprendo a trabalhar com o claro" | sed 's/claro/escuro/g'
4)
echo "Testando o líquido : Aprendo a trabalhar com o líquido" | sed 's/líquido/sólido/g'
5)
mkdir -vp SedTeste/SubDirSed
cd SedTeste/SudDirSed/
echo "Testando o líquido : Aprendo a trabalhar com o líquido" | sed 's/líquido/sólido/' > ArqLiquido.txt
ls -t
6)
cat ArqLiquido.txt
7)
sed -i.bkp 's/líquido/sólido/' ArqLiquido.txt
ls -t
cat ArqLiquido.txt
.
USAR CARACTERES DE ESCAPE:
.
OBS:
Escapo caracteres usando barra invertida: \
.
Isto: /proc/cpuinfo tem que ser escapado. Fica assim:
\/proc\/cpuinfo
.
Isto: /etc/passwd tem que ser escapado. Fica assim:
\/etc\/passwd
.
EXECUTO:
.
1) echo "O arquivo /proc/cpuinfo possui importantes informações!"
2) echo "O arquivo /etc/passwd possui importantes informações!"
.
AGORA USO O SED:
.
1) echo "O arquivo /proc/cpuinfo possui importantes informações!" | sed 's,\/proc\/cpuinfo,\/etc\/passwd,'
.
OBS:
ENTÃO, ABAIXO A MESMA COISA QUE ACIMA; MAS DE UM MODO VISUAL MAIS ILEGÍVEL QUE ASSUSTA:
.
EXECUTO:
.
echo "O arquivo /proc/cpuinfo possui importantes informações!" | sed 's/\/proc\/cpuinfo/\/etc\/passwd/'
.
OBS:
SETE META CARACTERES PARA LEMBRAR.
1) ^ : começa com
2) $ : término de linha
3) . : qualquer caractere
4) [] : relação de valores possíveis para um caracter. Você pode especificar uma lista ( [abcde] ), uma faixa ( [0-9] ), ou várias faixas ( [a-zA-Z0-9] ).
5) \{\} : especifica quantas vezes o caractere pode se repetir. Por exemplo: “{2}” (duas vezes), “{2,5}” (duas a cinco vezes), “{2,}” (duas ou mais vezes).
6) | : operador lógico ou
7) .* : operador lógico e
.
OBS:
CURINGAS PARA NOME DE ARQUIVO (GLOBAIS) É DIFERENTE DE META CARACTERE.
1) Curinga Casa com... Exemplo
2) * Qualquer coisa *.txt
3) ? Um caractere qualquer arquivo-??.zip
4) [...] Qualquer um dos caracteres listados [Aa]rquivo.txt
5) [^...] Qualquer um caractere, exceto os listados [^A-Z]*.txt
6) {...} Qualquer um dos textos separados por vírgula arquivo.{txt,html}
.
CONTINUANDO...
.
SE EU QUISER SUBSTITUIR:
https://com.semanickzaine.wordpress/
POR:
https://semanickz.wordpress.com/
.
USO ESTE EXEMPLO:
sed 's,texto-a-ser-substituido,texto-novo,'
.
EXECUTO NO TERMINAL:
1) echo 'O endereço deste blog é https://com.semanickzaine.wordpress/'
2) echo 'O endereço deste blog é https://com.semanickzaine.wordpress/' | sed 's,https://com.semanickzaine.wordpress/,https://semanickz.wordpress.com/,'
3) echo ; echo 'O endereço deste blog é https://com.semanickzaine.wordpress/' | sed 's,https://com.semanickzaine.wordpress/,https://semanickz.wordpress.com/,' ; echo
.
RESULTADO:
~$ echo 'O endereço deste blog é https://com.semanickzaine.wordpress/' | sed 's,https://com.semanickzaine.wordpress/,https://semanickz.wordpress.com/,'
O endereço deste blog é https://semanickz.wordpress.com/
.
EXPRESSÃO CASADA NA EXPRESSÃO REGULAR PARA SUBSTITUIÇÃO SEM ENROLAÇÃO:
.
EXECUTO:
.
1) echo ; echo -e "O arquivo /proc/cpuinfo possui informações importantes! \nEste tutorial está em /home/user-whoami/Downloads. Há outros nesse diretório" ; echo
2) echo ; echo -e "O arquivo /proc/cpuinfo possui informações importantes! \nEste tutorial está em /home/user-whoami/Downloads. Há outros nesse diretório" | sed -r 's/(\/[^ .,]*)+/"&"/' ; echo
.
OBS:
1) O pipe | liga um comando a outro.
2) Aí vem o sed.
3) A opção “-r” usa o padrão estendido de expressões regulares - o mesmo usado por “egrep”. Isso possibilita o uso da lista negada.
4) inicia aspa simples '
5) s/ Significa substitua
6) A expressão regular fica entre parênteses ()
7) Escapo caracteres usando barra invertida: \
.
8) Esta é a expressão regular entre parênteses e com caractere de escape: (\/[^ .,]*)
OBS:
META CARACTERES
1) ^ (circunflexo): representa o começo da linha
2) $ (cifrão): representa o fim da linha
3) . (ponto): casa com um caractere qualquer
4) .* (curinga): casa qualquer coisa, é tudo ou nada
5) a+ (mais): casa a letra "a" uma ou mais vezes
6) a* (asterisco): casa a letra "a" zero ou mais vezes
7) a? (opcional): casa a letra "a" zero ou mais vezes
8) a{2} (chaves): casa a letra "a" duas vezes
9) a{2,} (chaves): casa a letra "a" no mínimo duas vezes
10) [abc] (lista): casa as letras "a" ou "b" ou "c"
11) [^abc] (lista): casa qualquer caractere, exceto "a", "b", e "c"
12) (isso|aquilo) (Ou): casa as strings "isso" ou "aquilo"
.
9) Uso o caractere & entre aspas duplas para me referir à expressão casada pela expressão regular que se refere a /.
.
SUBSTITUIR PARTES DE UM TEXTO E MANTER OUTRAS
.
Usar “retrovisores”, que inserem na string final os padrões casados na Expressão Regular inseridos em grupos (( e )).
O primeiro grupo casado é referenciado por \1, o segundo, por \2 e assim sucessivamente, até \9.
Por exemplo, vou manter apenas a primeira palavra de cada linha de um texto.
.
Uso este exemplo:
sed 's,texto-a-ser-substituido,texto-novo,'
.
Executo:
.
1) echo -e "Primeira palavra\nSegunda palavra\nTerceira palavra"
2) echo -e "Primeira palavra\nSegunda palavra\nTerceira palavra" | sed -r 's,^([a-zA-Z]+).*,\1,g'
.
OBS:
META CARACTERES
1) ^ (circunflexo): representa o começo da linha
2) $ (cifrão): representa o fim da linha
3) . (ponto): casa com um caractere qualquer
4) .* (curinga): casa qualquer coisa, é tudo ou nada
5) a+ (mais): casa a letra "a" uma ou mais vezes
6) a* (asterisco): casa a letra "a" zero ou mais vezes
7) a? (opcional): casa a letra "a" zero ou mais vezes
8) a{2} (chaves): casa a letra "a" duas vezes
9) a{2,} (chaves): casa a letra "a" no mínimo duas vezes
10) [abc] (lista): casa as letras "a" ou "b" ou "c"
11) [^abc] (lista): casa qualquer caractere, exceto "a", "b", e "c"
12) (isso|aquilo) (Ou): casa as strings "isso" ou "aquilo"
.
Executo:
echo -e "Primeira palavra\nSegunda palavra\nTerceira palavra" | sed -r 's/^([a-zA-Z]+).*/\1/g'
.
OBS:
No final do comando o modificador "g" trata a linha inteira
.
Executo:
echo "palavras1 palavras2 palavras3" | sed -r 's/([a-zA-Z0-9]+)/NULL/g'
.
Remover todas as palavras substituir por NULL. Executo:
echo "palavras1 palavras2 palavras3" | sed -r 's/([a-zA-Z0-9]+)/NULL/g'
.
Remover todas as palavras menos a primeira e substituir por NULL. Executo:
echo "palavras1 palavras2 palavras3" | sed -r 's/([a-zA-Z0-9]+)/NULL/2g'
OBS:
O “2” faz com que a substituição ocorra apenas a partir da segunda ocorrência do padrão.
.
Por padrão, o SED imprime na saída padrão todas as linhas lidas - e modificadas. A opção -n impede que o sed faça a impressão das linhas. É nessa situação que o modificador “p” é útil. Quando quiser imprimir somente as linhas alteradas pelo SED.
.
Executo:
echo -e "linha sem número \nLinha com números: 1 2 3 4 5 6 7 \nLinha com mais números 52 91" | sed -r -n 's/[0-9]+/X/gp'
.
Exemplos:
.
Supressão da 3a linha:
sed '3d' meu_arquivo.txt
.
Supressão da última linha:
sed '$d' meu_arquivo.txt
.
Supressão de todas as linhas vazias:
sed '/^$/d' meu_arquivo.txt sed '/./!d' meu_arquivo.txt
.
Supressão do intervalo compreendido entre as linhas 7 e 9:
sed '7,9d' meu_arquivo.txt
.
REVISO META CARACTERES
----------------------
1) . Ponto Curinga de um caractere
----------------------
2) [] Lista Casa qualquer um dos caracteres listados
----------------------
3) [^] Lista negada Casa qualquer caractere, exceto os listados
----------------------
4) ? Opcional O item anterior pode aparecer ou não (opcional)
----------------------
5) * Asterisco O item anterior pode aparecer em qualquer quantidade
----------------------
6) + Mais O item anterior deve aparecer no mínimo uma vez
----------------------
7) {,} Chaves O item anterior deve aparecer na quantidade indicada {mín,máx}
----------------------
8) ^ Circunflexo Casa o começo da linha
----------------------
9) $ Cifrão Casa o fim da linha
----------------------
10) \b Borda Limita uma palavra (letras, números e sublinhado)
----------------------
11) \ Escape Escapa um meta, tirando seu poder
----------------------
12) | Ou Indica alternativas (usar com o grupo)
----------------------
13) () Grupo Agrupa partes da expressão, é quantificável e multinível
----------------------
14) \1 Retrovisor Recupera o conteúdo do grupo 1
----------------------
15) \2 Retrovisor Recupera o conteúdo do grupo 2 (segue até o \9)
----------------------
16) .* Curinga Casa qualquer coisa, é o tudo e o nada
----------------------
17) ?? Opcional NG Idem ao opcional comum, mas casa o mínimo possível
----------------------
18) *? Asterisco NG Idem ao asterisco comum, mas casa o mínimo possível
----------------------
19) +? Mais NG Idem ao mais comum, mas casa o mínimo possível
----------------------
20) {}? Chaves NG Idem às chaves comuns, mas casa o mínimo possível
.
EXPRESSÕES REGULARES E O COMANDO SED
-----------------------
EXPLICANDO UMA EXPRESSÃO REGULAR:
-----------------------
'\*\..{3}$'
-----------------------
Na expressão regular acima, as aspas simples são usadas para proteger a expressão e impedir que o interpretador de comandos dê um significado diferente a qualquer um dos caracteres. O * e o . são um asterisco e um ponto, literalmente, por isso são escapados por uma barra invertida. O . (ponto) significa um caractere qualquer, que é quantificado pelo número entre as chaves que o sucede. No caso, procuro por três caracteres após um asterisco e um ponto, mas isto por si só também abrangeria os casos onde temos extensões com mais de três letras. Para evitar que isto aconteça, dizemos que estes três caracteres são sucedidos por um “fim de linha”, representado pelo cifrão.
-----------------------
Executo os comandos abaixo:
.
# crio um arquivo para os testes
echo "Eu gosto de água de ar e terra. 1234567890" > teste.txt
cat teste.txt
ls -t
# substituir água por ar e vice-versa
sed -i 's/\(água\) e \(ar\)/\2 e \1/' teste.txt ; cat teste.txt
# substituir vogais 'a' ou 'u' por 'x'
sed -i 's/[ou]/x/g' teste.txt ; cat teste.txt
# substituir numeros pares por 0
sed -i 's/[2468]/0/g' teste.txt ; cat teste.txt
# substituir numeros impares por nada
sed -i 's/[13579]//g' teste.txt ; cat teste.txt
# substituir 3 primeiros caracteres por nada
sed -i 's/^...//g' teste.txt ; cat teste.txt
# substituindo espaços por nada
sed -i 's/\s//g' teste.txt ; cat teste.txt
.
Já é um bom começo. Se não usa Linux, teste em um terminal online.
.
.
Até Breve!
🙂
.