[pt-BR] Usando o shell além do básico
Tags: shell, intermediate, ptbr, quick
Published: 2022-06-01 01:10:37

> Imagem: [Hackerman](https://www.deviantart.com/shiiftyshift/art/Hackerman-643435212), de shiiftyshift.

Tudo bem, talvez não sejam realmente indispensáveis, mas aprendê-las vai fazer com que você se sinta a própria Hackerperson.

Quando você lida com um sistema operacional compatível com POSIX (alguma variação de UNIX, BSD, Linux, MacOS X, etc), internamente existem dois canais principais para entrada e saída de dados: o _stdin_ e o _stdout_. Existem mais, mas vamos focar nesses dois.

Um executável pode ler dados de _stdin_ e gravar dados em _stdout_. Um exemplo disso acontecendo é quando o programa lê dados do teclado e grava, ou exibe, na tela.

O pulo do gato acontece quando você conecta o _stdout_ de um programa com o _stdin_ de outro usando um recurso chamado pipe (cano ou encanamento). O que um programa exibiria na tela passa a ser enviado para o _stdin_ do programa seguinte, que processa aquelas entradas e devolve para o _stdout_. Você pode conectar inúmeros programas uns nos outros através do _pipe_, fazendo com que cada pecinha resolva uma parte do problema, transformado o dado e passando para o próximo.

![O fundamento mais básico da computação](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/st4ymex0c304uykwumv3.png)

Para nosso exemplo, vamos baixar um arquivo com praticamente todas as palavras da Língua Portuguesa [aqui](https://github.com/pythonprobr/palavras/raw/master/palavras.txt).

Executando `cat palavras.txt` serão exibidas na tela as mais de trezentas e vinte mil palavras do arquivo. `cat` lê o arquivo e joga seu conteúdo para _stdout_, que neste caso é a própria tela.

Vamos usar o pipe para exibir o arquivo em ordem alfabética invertida usando `sort`:

```bash
$ cat palavras.txt | sort -r
```
Agora, com o caracter de _pipe_, o `|`, direcionamos o conteúdo da saída padrão de `cat` para a entrada padrão de `sort`, exibindo assim o arquivo em ordem alfabética invertida.

Pode pode paginar a visualização do arquivo usando `less` e outro pipe:
 
```bash
$ cat palavras.txt | sort -r | less
```
Pressione espaço para ir para a próxima página, ou Q para sair.

Vamos exibir apenas as palavras do dicionário que contenham o texto _pli_. Para isso usamos `grep`, que retorna apenas as entradas que contenham o texto informado:

```bash
$ cat palavras.txt | grep pli
```

> Sim, você pode usar `grep palavras.txt pli` também, mas a ideia aqui é encadear vários _pipes_ para fins didáticos.

E vamos usar `sed` para deixar a primeira letra de cada palavra em maiúscula. `sed` aplica uma expressão regular na entrada e retorna o resultado:

```bash
$ cat palavras.txt | grep pli | sed 's/[a-z]/\U&/'
```

Para sabermos quantas palavras existem em nossa seleção, usamos `wc`:

```bash
$ cat palavras.txt | grep pli | wc -l
> 382
```
Agora, em outro exemplo, vamos listar os arquivos em um diretório qualquer:
```bash
$ ls -l
```
![ls -l](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjye4qshy4idt0f495jp.png)
Perceba que os dados vieram exibidos em colunas. Para pegar o conteúdo de apenas uma das colunas, usamos `awk`, que usa uma linguagem própria com o mesmo nome. Os nomes dos arquivos estão na nona coluna. Então, para selecioná-la, passamos essa informação para o `awk`:

```bash
$ ls -l | awk '{print $9}'
```
![ls -l | awk '{print $9}'](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vq4zsk3zr5j08wp9njyh.png)
 
> Sim, você poderia ter usado `file` para isso, mas estou claramente inventando situações para poder demonstrar as ferramentas.

Por fim, vamos usar `xargs`, que pega os valores que chegam pelo _stdin_ e passam como parâmetros para o comando seguinte. Por exemplo, vamos listar os arquivos e os conteúdos dos diretórios usando `ls`:

```bash
ls -l | awk '{print $9}' | xargs ls
```
![ls -l | awk '{print $9}' | xargs ls](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zj05wyexcc4wpx40cbl1.png)