The AWK language is a text processing language created for early versions of Unix. You can think of it as the grandfather of RegEx, as you could create simple scripts to search for text on the lines of files you wanted and then filter them.
The first version of this language appeared in 1977 as a scripting language for text processing, helping to increase the power of shell scripts and offer new functionalities, characteristics that made AWK influence several other languages, such as Perl, the new versions of Shell and Lua.
The language even had updates from the 1980s, making it possible to incorporate RegEx into the original AWK scripts.
With the end of Unix and the construction of GNU/Linux, BSD and other variations, the original AWK was in the past. However, mainly to maintain the backward compatibility of the scripts of the Unix users, several interpreters of the AWK appeared. The most popular are:
There are two ways to run AWK. One of them is putting the command inline, all on the same line, and executing it directly from the terminal. The second is by entering the entire command inside a file and executing that file
The first time you can run it directly in the terminal. Run the following command:
awk 'BEGIN{print "Hello World!"}'
This will print Hello World in the terminal. Simple, do you agree?
BEGIN {
print "Hello World!";
}
You can run it in 2 ways. First, run the file with the following command:
awk -f hello.awk
And that's it, you'll have Hello World written on the screen.
In the second (and most common) way, you add a hashbang before the code, with the following code:
#!/bin/gawk -f
This will tell the shell which interpreter will be used to run the script. Save the file and run the following command:
chmod +x hello.awk
This adds execute permission to the hello.awk file. Now just run:
./hello.awk
And that's it, you'll have Hello World written on the screen.
Let's work with the gender_submission.csv file from a Kaggle Titanic dataset (available here). Let's start by printing all the lines of the file:
cat gender_submission.csv | awk '{print $0;}'
For this file you will need to change the default divisor of items. The AWK default is a space, but our file uses the CSV default, which is a comma. How to change it? Simple, let's use the BEGIN block. The BEGIN block is executed once in the code, before everything else, while the following block is executed once per line. So let's change the FS variable, which sets the line parameter separator, right before running the rest of the code:
cat gender_submission.csv | awk 'BEGIN{FS=",";} {print $0;}'
Want to know if it worked? How about placing two arrows between one field and another?
cat gender_submission.csv | gawk 'BEGIN{FS=",";}{print $1 " → → " $2}'
Our aim here is to list only the IDs, but only of the people who survived. How can we do that? The answer is: adding an if conditional. When parameter 2 is equal to 1, it means it survived, and if it survived, we can show it on the screen. Our code looks like this:
cat gender_submission.csv | gawk 'BEGIN{FS=",";}{if ($2 == 1) print($1);}'
And that's it, you'll have a list of desired IDs. Simple, no?
You can still throw the output to a file:
(cat gender_submission.csv | gawk 'BEGIN{FS=",";}{if ($2 == 1) print($1);}') \
>> titanic_survivors_id.txt
Note that I put the command for printing outputs on another line in the shell to improve visibility.
You can also do the same thing by running commands directly from a file. How to do this? Come with me and I'll show you.
First write all your code inside a gs.awk file:
BEGIN {
FS=",";
}
{
if ($2 == 1)
print($0);
}
And save the file in the same folder as the file. Now, you can run the command like this:
cat gender_submission.csv | gawk -f gs.awk >> titanic_survivors_id.txt
We can simplify it even further using the hashbang. Just insert the following line at the top of the file:
#!/bin/gawk -f
Your code will look like this:
#!/bin/gawk -f
BEGIN {
FS=",";
}
{
if ($2 == 1)
print($0);
}
Now save the file and add execute permission to the file:
chmod +x gs.awk
And then your command will look like this:
cat gender_submission.csv | ./gs.awk >> titanic_survivors_id.txt
Of course, there are infinite other improvements we could make, like printing the lines directly to the correct file, but for an introduction, it was already quite interesting, don't you agree?
In case you want to study, there are several complex projects that challenge the limitations of the language, as well as comprehensive tutorials that explore specific details of the language. Here are some cool repositories:
A linguagem AWK é uma linguagem para processamento de texto criada para as primeiras versões do Unix. Você pode pensar nela como o avô do RegEx, já que você conseguia criar scripts simples para pesquisa de texto nas linhas dos arquivos que você queria e aí filtrá-las.
A primeira versão dessa linguagem surgiu em 1977 como uma linguagem de script para processamento de textos, ajudando a aumentar o poder dos scripts shell e oferecer novas funcionalidades, características que fizeram o AWK influenciar diversas outras linguagens, como Perl, as novas versões do Shell e Lua.
A linguagem ainda teve atualizações a partir dos anos 80, possibilitando a incorporação do RegEx dentro dos scripts AWK originais.
Com o fim do Unix e construção do GNU/Linux, BSD e outras variações, o AWK original ficou no passado. Porém, principalmente para manter a retrocompatibilidade dos scripts dos usuários do Unix, surgiram diversos interpretadores do AWK. Os mais populares são:
Há duas formas de se executar AWK. Uma delas é colocando o comando inline, todo em uma mesma linha, e executá-lo diretamente pelo terminal. A segunda é inserindo o comando inteiro dentro de um arquivo e executando esse arquivo
Na primeira vez você pode rodar direto no terminal. Rode o seguinte comando:
awk 'BEGIN{print "Hello World!"}'
Isso vai imprimir Hello World no terminal. Simples, não?
BEGIN {
print "Hello World!";
}
Você pode rodar de 2 formas. Na primeira você deve rodar o arquivo com o seguinte comando:
awk -f hello.awk
E pronto, você vai ter Hello World escrito na tela.
Na segunda forma (e mais comum), você adiciona, antes do código, uma hashbang, com o seguinte código:
#!/bin/gawk -f
Isso indicará para o shell qual o interpretador que será usado para rodar o script. Salve o arquivo e rode o seguinte comando:
chmod +x hello.awk
Isso adiciona permissão de execução ao arquivo hello.awk. Agora é só executar:
./hello.awk
E pronto, você terá Hello World escrito na tela.
Vamos trabalhar com o arquivo gender_submission.csv de um dataset do Titanic da Kaggle (disponível aqui). Comecemos imprimindo todas as linhas do arquivo:
cat gender_submission.csv | awk '{print $0;}'
Para esse arquivo você vai precisar alterar o divisor padrão dos items. O padrão do AWK é um espaço, mas o nosso arquivo usa o padrão do CSV, que é uma vírgula. Como mudar isso? Simples, vamos usar o bloco BEGIN. O bloco BEGIN é executado uma única vez no código, antes de todo o resto, enquanto o seguinte é executado uma vez por linha. Então vamos alterar a variável FS, que define o separador dos parâmetros da linha, logo antes de executar o resto do código:
cat gender_submission.csv | awk 'BEGIN{FS=",";} {print $0;}'
Quer saber se deu certo? Que tal colocar duas setas entre um campo e outro?
cat gender_submission.csv | gawk 'BEGIN{FS=",";}{print $1 " → → " $2}'
O nosso objetivo aqui é listar somente os IDs, mas apenas das pessoas que sobreviveram. Como podemos fazer isso? A resposta é: adicionando uma condicional if. Quando o parâmetro 2 for igual a 1, significa que sobreviveu, e, se sobreviveu, podemos mostrar na tela. Nosso código fica assim:
cat gender_submission.csv | gawk 'BEGIN{FS=",";}{if ($2 == 1) print($1);}'
E pronto, você terá uma lista dos IDs desejados. Simples, não?
Você ainda pode jogar a saída para um arquivo:
(cat gender_submission.csv | gawk 'BEGIN{FS=",";}{if ($2 == 1) print($1);}') \
>> titanic_survivors_id.txt
Perceba que eu coloquei o comando para impressão de saídas em outra linha no shell para melhorar a visibilidade.
Você pode também fazer a mesma coisa rodando os comandos diretamente de um arquivo. Como fazer isso? Vem comigo que eu vou te mostrar.
Primeiro escreva seu código todo dentro de um arquivo gs.awk:
BEGIN{
FS=",";
}
{
if ($2 == 1)
print($0);
}
E salve o arquivo na mesma pasta do arquivo. Agora, você pode rodar o comando assim:
cat gender_submission.csv | gawk -f gs.awk >> titanic_survivors_id.txt
Podemos simplificar ainda mais usando a hashbang. É só inserir a seguinte linha no topo do arquivo:
#!/bin/gawk -f
Seu código vai ficar assim:
#!/bin/gawk -f
BEGIN{
FS=",";
}
{
if ($2 == 1)
print($0);
}
Agora salve o arquivo e adicione permissão de execução ao arquivo:
chmod +x gs.awk
E pronto, seu comando ficará assim:
cat gender_submission.csv | ./gs.awk >> titanic_survivors_id.txt
Claro que existem infinitas outras melhorias que poderíamos fazer, como imprimir as linhas diretamente no arquivo correto, mas, para uma introdução, já foi bem interessante, concorda?
Caso você queira estudar, existem vários projetos complexos que desafiam as limitações da linguagem, assim como tutoriais completos que exploram detalhes específicos da linguagem. Aqui vão alguns repositórios interessantes: