- awk to narzędzie i język skryptowy zorientowany na przetwarzanie tekstu za pomocą wierszy i kolumn, idealny do filtrowania, przekształcania i analizowania wyników polecenia i pliki.
- Umożliwia definiowanie wzorców i działań poprzez łączenie wyrażeń regularnych, zmiennych specjalnych, takich jak $0, $1, NF lub NR, i funkcji, takich jak length, substr lub match, co pozwala na tworzenie bardzo precyzyjnych filtrów.
- awk współpracuje wygodnie z ogranicznikami i polami, używając FS, OFS i opcji takich jak -F, i może forma łza wyprowadza dane za pomocą print i printf, wykonuje operacje matematyczne i zarządza zmiennymi za pomocą -v.
- Możliwe jest tworzenie kompletnych skryptów awk automatyzujących złożone zadania, w tym wyszukiwanie i zamianę za pomocą gsub, zaawansowane obliczenia i generowanie raportów z poleceń, takich jak ps, df lub pliki systemowe.

Kiedy zaczynasz traktować konsolę poważnie Linux Odkrywasz, że praca z tekstem nie polega tylko na przeglądaniu plików cat I to tyle. Jak tylko wejdziesz do środka, dzienniki W przypadku ogromnych list procesów, wyników poleceń lub plików CSV potrzebne jest coś o wiele bardziej wydajnego, co pozwoli na filtrowanie, przekształcanie i podsumowywanie danych bez popadania w szaleństwo.
Tu właśnie pojawia się awk.:polecenie, które jest czymś więcej niż prostym filtrem, jest praktycznie językiem programowanie Awk to narzędzie do przetwarzania tekstu, które pozwala wyszukiwać wzorce, zaznaczać kolumny, wykonywać obliczenia, definiować warunki, używać zmiennych, pętli, funkcji, a nawet pisać kompletne skrypty. W tym samouczku dotyczącym Awk dla Linuksa omówimy je krok po kroku, od podstaw do dość zaawansowanych zastosowań, wykorzystując wszelkiego rodzaju praktyczne przykłady z konsoli.
Czym jest awk i do czego służy w systemie Linux?
Awk jest zarówno narzędziem wiersza poleceń, jak i językiem skryptowym Zaprojektowany do analizy tekstu ustrukturyzowanego w wierszach i polach, jego nazwa pochodzi od inicjałów jego twórców (Aho, Weinberger i Kernighan). Jest używany od końca lat 70. XX wieku, ale nadal pozostaje kluczowym elementem w każdym środowisku. Unix lub GNU/Linux (na przykład dla Uruchom starego Unixa na swoim komputerze).
Filozofia awk jest bardzo prosta: Iteruje plik (lub wynik polecenia) wiersz po wierszu, dzieląc każdy wiersz na kolumny według separatora, sprawdza, czy warunek jest spełniony i jeśli tak, wykonuje akcję. Jeśli warunek nie zostanie określony, akcja zostanie zastosowana do wszystkich wierszy; jeśli nie zostanie określona akcja, domyślną akcją jest wydrukowanie całego wiersza.
Dzięki temu prostemu mechanizmowi możesz zdziałać naprawdę niesamowite rzeczy.:z pokazywania tylko niektórych kolumn ps o df...po obliczeniu sum, filtrowaniu według złożonych wzorców za pomocą wyrażeń regularnych, zastępowaniu tekstu, formatowaniu raportów, pracy z plikami CSV, a nawet pisaniu skryptów składających się z kilkudziesięciu wierszy.
Chociaż awk może trochę przypominać grep lub sedPodejście tego programu jest bardziej ustrukturyzowane: wiersze można traktować jak rekordy, a słowa (lub pola) jak kolumny. Zawiera on zmienne wewnętrzne i mini-język, co sprawia, że idealnie nadaje się do szybkiego przetwarzania danych tabelarycznych.
W praktyce, jeśli chcesz zacząć pisać porządne skrypty powłoki...Znajomość awk i innych narzędzi, takich jak sed, grep, cut i spółki. Są to podstawowe elementy składowe przetwarzania tekstu w systemie Linux.
Zainstaluj i uruchom awk (gawk) w swoim systemie
W większości współczesnych dystrybucji GNU/Linuxawk jest już zainstalowany domyślnie, zazwyczaj w wariancie GNU awk (gawkMożesz to sprawdzić za pomocą:
awk --version
Jeśli z jakiegoś powodu nie masz go zainstalowanegoW Debianie, Ubuntu i pochodnych możesz użyć menedżera pakietów:
sudo apt update && sudo apt install gawk
Jest dostępna również na macOS.Możesz użyć wersji systemowej lub zainstalować zaktualizowaną wersję za pomocą Homebrew:
brew install gawk
Po zainstalowaniu awk jest zawsze używany z tą samą ideą.Przekazujesz instrukcje między pojedynczymi cudzysłowami a plikiem (lub przesyłasz dane wyjściowe innego polecenia). Na przykład:
awk '{print}' archivo.txt
Możesz również używać awk jako interpretera skryptów, wskazując ścieżkę do pliku wykonywalnego w pierwszym wierszu pliku:
#!/usr/bin/awk -f
a następnie uruchomienie scenariusz bezpośrednio lub z awk -f script.awk.
Podstawowa składnia: wzorce i akcje

Minimalna struktura awk wygląda następująco:
awk 'patrón { acción }' fichero
Każdy wiersz pliku jest porównywany ze wzorcem.Jeśli pasuje, wykonywana jest akcja w nawiasach klamrowych. Jeśli pominiesz wzorzec, akcja zostanie zastosowana do wszystkich wierszy. Kilka kluczowych pomysłów:
Zmienne specjalne odnoszące się do każdej linii:
$0:cała linia.$1, $2, $3, …: pola (kolumny) wiersza, rozdzielone zdefiniowanym ogranicznikiem.NF: liczba pól w bieżącym wierszu.NR: aktualny numer rejestracyjny (globalny numer linii).FNR: numer wiersza w bieżącym pliku, przydatny podczas przetwarzania wielu plików.
Instrukcje specjalne:
BEGIN { … }: blok wykonywany przed odczytaniem dowolnego wiersza.END { … }:blok wykonywany po przetworzeniu wszystkich wierszy.
Najczęstsze polecenia wyjściowe:
print: drukuje argumenty oddzielone separatorem wyjściowym (OFS(domyślnie spacja).printf:podobny doprintfW języku C umożliwia szczegółowe formatowanie bez dodawania automatycznych podziałów wiersza.
Minimalny przykład drukowania pliku dokładnie w takiej postaci, w jakiej jest, tak jakby był cat:
awk '{print}' archivo.txt
Lub jeśli chcesz, aby pokazywała również długość każdej linii:
awk '{print length, "\t", $0}' archivo.txt
Praca z kolumnami i separatorami w awk
Jednym z głównych zastosowań awk jest manipulowanie kolumnami z wyników poleceń, takich jak ps, df lub pliki takie jak /etc/passwdDomyślnie awk traktuje każdą spację lub tabulator jako separator, ale możesz użyć praktycznie dowolnego rozgranicznika.
Wybierz konkretne kolumny
Wyobraź sobie wyjście ps z kilkoma kolumnami (PID, TTY, TIME, CMD…)Jeśli chcesz zobaczyć tylko PID-y, po prostu:
ps | awk '{print $1}'
Jeśli interesuje Cię druga kolumna (np. TTY):
ps | awk '{print $2}'
A jeśli chcesz pominąć pierwszy wiersz (nagłówek)Można filtrować według numeru rejestracyjnego:
ps | awk 'NR>1 {print $1}'
Pomysł jest bardzo prosty.:każda liczba po symbolu $ Odnosi się do odpowiedniej kolumny, zawsze z uwzględnieniem bieżącego separatora.
Zmień ogranicznik za pomocą -F i FS
Wiele plików systemowych nie jest rozdzielonych spacjami.ale przez innych symboleKlasyka to /etc/passwdgdzie pola są rozdzielone przez :Aby przetworzyć plik według kolumn, masz dwie opcje: opcję -F na wierszu poleceń lub zmiennej FS wewnątrz bloku BEGIN.
Używanie opcji -F w wierszu poleceń:
cat /etc/passwd | awk -F ":" '{print $1}'
Ten przykład pokazuje tylko nazwy użytkowników (pierwsze pole), ponieważ separator jest teraz :Jeśli chcesz również uzyskać UID i GID (pola 3 i 4), po prostu:
cat /etc/passwd | awk -F ":" '{print $1, $3, $4}'
Problem z tym poleceniem jest taki, że dane wyjściowe są ze sobą powiązane. Jeśli nie zdefiniujesz wyraźnych separatorów, możesz dodać spacje lub tabulatory ręcznie:
cat /etc/passwd | awk -F ":" '{print $1 " " $3 " " $4}'
Jeśli chcesz uzyskać bardziej tabelaryczny wynikmożesz użyć \t aby wstawić tabulatory:
cat /etc/passwd | awk -F ":" '{print $1 "\t" $3 "\t" $4}'
Alternatywa z FS w bloku BEGIN Umożliwia ustawienie separatora wewnątrz samego skryptu awk:
cat /etc/passwd | awk 'BEGIN { FS=":" } {print $1 "\t" $3 "\t" $4}'
Oba podejścia są funkcjonalnie równoważnechociaż używając BEGIN {FS=...} Zazwyczaj jest czyściej, gdy piszesz skrypty .awk, które można ponownie wykorzystać.
FS i OFS: separatory wejściowe i wyjściowe
Oprócz FS (separatora pól) awk ma OFS (separator pól wyjściowych)który definiuje sposób rozdzielania pól podczas korzystania z print z przecinkami:
cat /etc/passwd | awk 'BEGIN { FS=":"; OFS=" - " } {print $1, $3, $4}'
W tym przypadku czytasz z : ale piszesz z - , generując dane wyjściowe takie jak:
root - 0 - 0
daemon - 1 - 1
...
Ta kombinacja FS/OFS jest bardzo przydatna do „ponownego formatowania” danychNa przykład w celu konwersji z jednego formatu na inny lub przygotowania czytelnych danych wyjściowych, które można następnie wyeksportować do innego systemu.
Pobierz ostatnie pole za pomocą $NF (i poprzednie)
W wielu wynikach poleceńPole, które Cię interesuje, znajduje się na końcu, ale dokładna liczba kolumn może się różnić. To właśnie tam $NF (Liczba pól) ułatwia życie: jest to zawsze ostatnie pole w bieżącym wierszu.
Dla przykładu, w /etc/shells Prawidłowe ścieżki powłoki znajdują się na końcu każdego wierszaCzasami w drugiej kolumnie, czasami w trzeciej itd. Aby wydrukować tylko nazwę powłoki (część po ostatnim ukośniku):
awk -F "/" '/^\// {print $NF}' /etc/shells
Jeśli chcesz zachować tylko unikalne wartości (bez duplikatów), można łączyć łańcuchowo uniq:
awk -F "/" '/^\// {print $NF}' /etc/shells | uniq
A jeśli interesuje Cię przedostatni element ścieżki (na przykład poprzedni katalog), możesz użyć $(NF-1) o $(NF-2):
awk -F "/" '/^\// {print $(NF-1)}' /etc/shells
awk -F "/" '/^\// {print $(NF-2)}' /etc/shells
Filtruj linie według wzorców, długości i warunków logicznych
Awk sprawdza się, gdy chcesz trzymać się tylko określonych wierszy na podstawie wzorców tekstowych, określonych kolumn lub warunków liczbowych. Łącz wyrażenia regularne, operatory logiczne i funkcje, takie jak length aby tworzyć bardzo precyzyjne filtry.
Filtruj według wzorców i wyrażeń regularnych
Najbardziej bezpośrednią metodą filtrowania według zawartości jest umieszczenie wyrażenia regularnego pomiędzy ukośnikami. Tuż przed klawiszami:
awk '/patrón/ {print}' archivo.txt
Na przykład wraz z odejściem df Można wyświetlić tylko wiersze zaczynające się od ukośnika (zamontowane systemy plików):
df | awk '/^\// {print}'
Jeśli chcesz konkretną partycję, np. /dev/sda5:
df | awk '/^\/dev\/sda5/ {print}'
Można również filtrować według wzorców na początku lub na końcu linii przy ^ y $:
awk '/^tmpfs/ {print}' archivo.txt
awk '/\/shm$/ {print}' archivo.txt
I połącz kilka kryteriów za pomocą operatora logicznego &&Na przykład linie zaczynające się od tmpfs i kończą się w /dev/shm:
df | awk '/\/shm$/ && /^tmpfs/ {print}'
Filtruj według kolumn i wyświetlaj tylko to, co Cię interesuje
Często chcesz filtrować nie tylko wiersze, ale i kolumny.Kontynuując df -h, możesz pokazać tylko prawdziwe systemy plików (^/) a następnie zachowaj kolumny 1, 2 i 3:
df -h | awk '/^\// {print $1 "\t" $2 "\t" $3}'
Awk pozwala nawet na pracę z polami w locieNa przykład dodaj kolumny 2 i 3 (używane + dostępne), aby zobaczyć obliczoną „całkowitą pojemność”:
df -h | awk '/^\// {print $1 "\t" $2 + $3}'
Jeśli chcesz dodać jednostkę dosłowną „G” na końcu wyniku:
df -h | awk '/^\// {print $1 "\t" $2 + $3 "G"}'
Filtruj według długości linii za pomocą length()
Funkcja length() mierzy liczbę znaków w ciąguZwykle jest używany z $0 (pełna linia), ale można jej również używać z konkretną kolumną.
Aby wyświetlić tylko linie /etc/shells z więcej niż 9 znakami:
awk 'length($0) > 9' /etc/shells
Jeśli chcesz zobaczyć długość każdej linii:
awk '{print length, "\t", $0}' /etc/shells
Można również filtrować według długości, a następnie drukować tylko długość.:
awk 'length($0) > 9 {print length}' /etc/shells
Połącz wiele warunków za pomocą && i if
Oprócz używania wyrażeń regularnych na początkuMożesz zapisać kompletne warunki w bloku, używając if, porównania i operatory logiczne.
Na przykład wyświetlanie tylko linii df -h które zaczynają się od t i którego kolumna 6 ma więcej niż 8 znaków:
df -h | awk '/^t/ && length($6) > 8 {print $0}'
Innym typowym przypadkiem jest wyszukiwanie procesów według ostatniego pola (polecenie wykonane) na wyjściu ps -efOstatnie pole to $NFMożesz więc użyć:
ps -ef | awk '{ if ($NF == "firefox") print $0 }'
Jeśli interesuje Cię tylko PID i polecenie:
ps -ef | awk '{ if ($NF == "firefox") print $2, $NF }'
Linie sterujące z NR, zakresami i długością pola
Zmienna NR (liczba rekordów) Zlicza, ile wierszy zostało już odczytanych (globalnie). Pozwala to na wykonywanie typowych czynności, takich jak pomijanie nagłówków, drukowanie określonych zakresów wierszy lub wyświetlanie tylko pierwszego wiersza.
Policz linie i pokaż tylko pierwszą lub drugą
Aby policzyć całkowitą liczbę wierszy w pliku nieużywany wc -l Możesz zrobić:
awk 'END {print NR}' archivo.txt
Jeśli chcesz wydrukować tylko pierwszy wiersz:
awk 'NR==1 {print}' archivo.txt
I pokazać tylko drugą linię:
awk 'NR==2 {print}' archivo.txt
Drukuj zaczynając od określonej linii lub zakresu
Aby wyświetlić wszystkie linie od trzeciej w górę Możesz użyć prostego warunku z > o >=:
ps -aux | awk 'NR>2 {print}'
Jeśli chcesz zakres, na przykład linie od 2 do 4 en /etc/shells:
cat /etc/shells | awk 'NR==2, NR==4 {print $0}'
Można również wydrukować numer wiersza obok zawartości:
cat /etc/shells | awk 'NR==2, NR==4 {print NR, $0}'
Długość określonych pól
Oprócz pomiaru długości całych liniiMożesz sprawdzić długość konkretnej kolumny. Na przykład, aby zobaczyć, ile znaków ma system plików (kolumna 1) w wynikach df -h:
df -h | awk '{print length($1) "\t" $1}'
Jeśli chcesz pominąć nagłówek (pierwszy wiersz) dodaje NR>1:
df -h | awk 'NR>1 {print length($1) "\t" $1}'
Przydatne funkcje: substr, match, RSTART i RLENGTH
Awk zawiera dobry zestaw funkcji tekstowychDwa z najpotężniejszych narzędzi do zaawansowanego wyszukiwania to: substr y match, temu ostatniemu towarzyszą zmienne RSTART y RLENGTH.
Przytnij tekst za pomocą substr()
Funkcja substr(cadena, inicio) o substr(cadena, inicio, longitud) Umożliwia wyodrębnianie podciągów. Na przykład, aby usunąć pierwsze 5 znaków z każdego wiersza /etc/shells:
cat /etc/shells | awk '{print substr($0, 5)}'
Jeśli nie chcesz przetwarzać pierwszej linii (na przykład komentarz), możesz użyć NR:
cat /etc/shells | awk 'NR>1 {print substr($0, 5)}'
Należy pamiętać, że pierwszym parametrem jest ciąg znaków (zwykle $0) a drugi wskazuje, który znak chcesz zacząć wyświetlać.
Lokalizowanie wzorców za pomocą match(), RSTART i RLENGTH
Funkcja match(cadena, /regex/) wyszukaj wyrażenie regularne w ciąguJeśli zostanie znalezione dopasowanie, zwracana jest pozycja początkowa (na podstawie 1) i wypełniane są dwie zmienne:
RSTART: pozycja, w której zaczyna się znaleziony wzór.RLENGTH:długość meczu.
Na przykład dla wszystkich linii ps -aux zawierające „cpu”Można wyświetlić całą linię i pozycję, w której znajduje się wzór:
ps -aux | awk 'match($0, /cpu/) {print $0 " Contiene \"cpu\" en la posición " RSTART}'
Jeśli chcesz również poznać wymiary znalezionego wzoru, po prostu użyj RLENGTH przy wyjściu:
ps -aux | awk 'match($0, /cpu/) {print $0 " Posición=" RSTART " Longitud=" RLENGTH}'
Ten typ wyszukiwania jest szeroko stosowany w analizie tekstu i bioinformatyceNa przykład w plikach FASTA, gdy interesuje Cię znalezienie konkretnych motywów w sekwencjach.
Operacje matematyczne i zmienne w awk
Awk nie ogranicza się do wyświetlania tekstu: umożliwia wykonywanie operacji numerycznych bezpośrednio na polach, zmiennych wewnętrznych lub wartościach przekazywanych z wiersza poleceń lub ze środowiska powłoki.
Zdefiniuj zmienne za pomocą -vy i użyj ich na początku
Możesz deklarować zmienne za pomocą opcji -v podczas wywoływania awkNa przykład mnożąc dwie stałe liczby:
awk -v a="10" -v b="20" 'BEGIN {print "La multiplicación de a x b es", a*b}'
Możliwe jest również przekazywanie wartości zmiennych z powłokiJeśli w bash'u wykonasz:
a=1.5
b=4
Następnie możesz ich używać w awk w ten sposób:
awk -v a="$a" -v b="$b" 'BEGIN {print "La multiplicación de a x b es", a*b}'
Blok BEGIN został tutaj użyty, ponieważ nie przetwarzamy żadnego pliku.Chcemy po prostu uruchomić kod raz i wyświetlić wynik.
Funkcje matematyczne: pętle sqrt i for
Awk zawiera kilka standardowych funkcji matematycznych.Jak sqrt() dla pierwiastków kwadratowych. Na przykład pierwiastek kwadratowy z 400:
awk 'BEGIN {print sqrt(400)}'
Można również połączyć go z pętlami for aby wygenerować kompletne listy:
awk 'BEGIN { for(i=1; i<=10; i++) print "La raíz cuadrada de", i*i, "es", i }'
Lub przechodź wartości dziesiętne od 0 do 1 w małych krokach:
awk 'BEGIN { for(i=0; i<=1; i=i+0.00001) print "La raíz cuadrada de", i*i, "es", i }'
Tego typu struktury sprawiają, że AWK jest bardzo podobny do języka tradycyjnegochociaż jego naturalnym środowiskiem pozostaje format kolumnowy.
Pisanie i uruchamianie kompletnych skryptów w awk
Kiedy polecenia awk zaczynają być długie Jeśli chcesz ponownie wykorzystać złożone transformacje, rozsądnym rozwiązaniem jest zapisanie ich w pliku skryptu z rozszerzeniem . .awk (choć nie jest to obowiązkowe).
Typowy przykład obejmuje przetwarzanie danych wyjściowych df wyświetlanie tylko niektórych wpisów, które spełniają warunki dotyczące dostępnego miejsca, oraz formatowanie wyników w postaci małej tabeli.
Wyobraź sobie, że chcesz czegoś takiego:
- Pokaż tylko systemy plików, których nazwa zaczyna się od „t” (na przykład
tmpfs). - Filtruj te, których dostępna pojemność (kolumna 4) jest większa niż 6000K.
- Wypisz tylko jednostkę (kolumna 1) i sumę kolumn 2 i 3 jako przybliżoną przestrzeń całkowitą.
Możesz utworzyć skrypt o nazwie capacidad.awk z podobną treścią (zaadaptowane i uproszczone):
#!/usr/bin/awk -f
BEGIN { printf "%s\n", "Voy a extraer las partes que me interesan del comando df" }
BEGIN { printf "%s\t%s\n", "Unidad", "Capacidad disponible" }
/^t/ && $4 > 6000 {print $1 "\t" $2 + $3 "K"}
A następnie wykonaj go, łącząc wyjście df.:
df | awk -f capacidad.awk
Jeśli chcesz poprawić wygląd tabeli, możesz zastąpić print przez printf i używać formatów takich jak %-12s (tekst wyrównany do lewej w 12 znakach) lub %-23d (Liczba dziesiętna składająca się z 23 znaków). Dzięki temu masz pełną kontrolę nad wyrównaniem kolumn.
Znajdź i zamień tekst za pomocą gsub()
Awk może również wykonywać zamiany tekstu podobnie do tego, co zrobiłbyś z sed, używając funkcji gsub() (globalny substytut).
Ogólna składnia to:
gsub("texto_o_regex_a_buscar", "texto_de_reemplazo", destino)
Na przykład załóżmy, że plik geekland.txt z tekstem „Geekland to najlepszy blog o technologii” i chcesz zmienić początkowe G na g:
awk '{ gsub("G", "g", $0); print $0 }' geekland.txt
Jeżeli nie zostanie określony trzeci parametr, wyszukiwanie zostanie przeprowadzone $0 domyślnieBardzo często jednak ogranicza się zamianę do jednej kolumny:
df -h | awk '{ gsub("M", "G", $2); print $2 }'
W tym przypadku zmieniliśmy tylko jednostkę M na G w kolumnie 2Jeśli chcesz również prawidłowo wyrównać kolumnę 1, możesz to połączyć z printf:
df -h | awk '{ gsub("M", "G", $2); printf "%-12s %-12s\n", $1, $2 }'
Ten wzorzec „Modyfikuję kolumnę, a następnie drukuję sformatowaną” Jest to narzędzie niezwykle przydatne przy tworzeniu raportów, migracji danych lub szybkim czyszczeniu wyników poleceń.
Dodatkowe zastosowania: kot zakażony sterydami i wykonywanie poleceń
Choć może się to wydawać głupieawk może działać jako cat Udoskonalono, ponieważ można wyświetlić plik, dodając jednocześnie dodatkowe informacje (numery wierszy, długości itp.).
Trywialnym zastosowaniem byłoby:
awk '{print}' functions.php
Można również ponumerować linie lub zastosować dowolny filtr. bez konieczności używania dodatkowych narzędzi.
Innym ciekawym faktem jest to, że awk może wykonywać polecenia systemowe używając funkcji system()Na przykład, aby wyświetlić bieżący katalog:
awk 'BEGIN { system("pwd") }'
Nie jest to najczęstsza praktyka w prostych skryptach.Ale dobrze jest wiedzieć, że istnieje taka możliwość, gdy tworzysz bardziej złożone narzędzia oparte na awk.
Awk staje się scyzorykiem szwajcarskim dla tekstu w LinuksieUmożliwia filtrowanie wierszy, zaznaczanie i łączenie kolumn, zastępowanie fragmentów, mierzenie długości, lokalizowanie wzorców, sumowanie pól, generowanie małych, sformatowanych raportów, a nawet tworzenie kompletnych skryptów przetwarzających dane wyjściowe innych poleceń. Gdy już się z nim oswoisz, stanie się niezbędnym narzędziem podczas pracy z... terminal i ustrukturyzowanych danych.
Pisarz z pasją zajmujący się światem bajtów i technologii w ogóle. Uwielbiam dzielić się swoją wiedzą poprzez pisanie i właśnie to będę robić na tym blogu, pokazywać Ci wszystkie najciekawsze rzeczy o gadżetach, oprogramowaniu, sprzęcie, trendach technologicznych i nie tylko. Moim celem jest pomóc Ci poruszać się po cyfrowym świecie w prosty i zabawny sposób.