Tips en Trucs 2023

Zoeken met Ack

Met het Linux besturingssysteem kun je zowel directory-structuren als directory-bestanden doorzoeken op specifieke tekst-overeenkomsten. Een veelgebruikt hulpmiddel bij deze zoekopdrachten in mappen is de grep-opdracht (global regular expression print). Het gebruik van reguliere expressies door grep maakt het mogelijk om een zoekopdracht te starten naar een overeenkomende tekst in de terminal.

De nadelen van grep liggen echter in de snelheid en de niet-flexibele mogelijkheden. Dit is waar het gereedschap ack het overneemt. Het geeft snelle zoekopdrachten die zich uitstekend lenen tot het doorzoeken van broncode mappen, terwijl het de Linux gebruiker de flexibiliteit geeft om bepaalde zoekresultaten uit te sluiten.

Ack installeren

In openSUSE Leap 15.4 installeer je ack via de standaard softwarebronnen met de opdracht:

dany@pindabook:~> sudo zypper install ack
[sudo] wachtwoord voor root: 
Ophalen van metagegevens uit opslagruimte 'Update repository of openSUSE Backports' ...........................................[gereed]
Cache van opslagruimte 'Update repository of openSUSE Backports' wordt gebouwd ................................................[gereed]
Ophalen van metagegevens uit opslagruimte 'Hoofd-opslagruimte voor bijwerken' .................................................[gereed]
Cache van opslagruimte 'Hoofd-opslagruimte voor bijwerken' wordt gebouwd ......................................................[gereed]
Gegevens van opslagruimte laden...
Lezen van geïnstalleerde pakketten...
Pakketafhankelijkheden oplossen...

De volgende 3 NIEUWE pakketten zullen worden geïnstalleerd:
  ack perl-App-Ack perl-File-Next

3 nieuwe te installeren pakketten.
Totale downloadgrootte: 120,0 KiB. Reeds in de cache: 0 B. Na de bewerking zal aanvullend 229,0 KiB worden gebruikt.
Doorgaan? [j/n/v/...? alle opties tonen] (j): 
pakket perl-File-Next-1.18-bp154.1.59.x86_64 wordt opgehaald                                     (1/3),  23,7 KiB ( 28,7 KiB uitgepakt)
Ophalen: perl-File-Next-1.18-bp154.1.59.x86_64.rpm ............................................................................[gereed]
pakket perl-App-Ack-3.5.0-bp154.1.15.noarch wordt opgehaald                                      (2/3),  46,3 KiB (110,9 KiB uitgepakt)
Ophalen: perl-App-Ack-3.5.0-bp154.1.15.noarch.rpm .............................................................................[gereed]
pakket ack-3.5.0-bp154.1.15.noarch wordt opgehaald                                               (3/3),  50,1 KiB ( 89,5 KiB uitgepakt)
Ophalen: ack-3.5.0-bp154.1.15.noarch.rpm ......................................................................................[gereed]

Controleren op conflicten tussen bestanden: ...................................................................................[gereed]
(1/3) Installeren van: perl-File-Next-1.18-bp154.1.59.x86_64 ..................................................................[gereed]
(2/3) Installeren van: perl-App-Ack-3.5.0-bp154.1.15.noarch ...................................................................[gereed]
(3/3) Installeren van: ack-3.5.0-bp154.1.15.noarch ............................................................................[gereed]

Mappen doorzoeken met ack

Aangezien ack goed is in het doorzoeken van broncode, kunnen we zijn zoekvaardigheid in tekstpatronen demonstreren via een map met broncode. Github is een bekende bron voor duizenden broncode projecten. Een ideaal project met broncode voor deze tip is het neovim-project.

Neovim broncode downloaden en uitpakken

Het archief met de Neovim broncode kan je van Github downloaden met de opdracht:

dany@pindabook:~> wget https://github.com/neovim/neovim/archive/refs/heads/master.zip
--2023-01-01 18:00:42--  https://github.com/neovim/neovim/archive/refs/heads/master.zip
Herleiden van github.com (github.com)... 140.82.121.3
Verbinding maken met github.com (github.com)|140.82.121.3|:443... verbonden.
HTTP-verzoek is verzonden; wachten op antwoord... 302 Found
Locatie: https://codeload.github.com/neovim/neovim/zip/refs/heads/master [volgen...]
--2023-01-01 18:00:42--  https://codeload.github.com/neovim/neovim/zip/refs/heads/master
Herleiden van codeload.github.com (codeload.github.com)... 140.82.121.9
Verbinding maken met codeload.github.com (codeload.github.com)|140.82.121.9|:443... verbonden.
HTTP-verzoek is verzonden; wachten op antwoord... 200 OK
Lengte: niet-opgegeven [application/zip]
Wordt opgeslagen als: ‘master.zip’

master.zip                            [           <=>                                               ]  12,22M  6,00MB/s    in 2,0s    

2023-01-01 18:00:44 (6,00 MB/s) - '‘master.zip’' opgeslagen [12817915]

En uitpakken met:

dany@pindabook:~> unzip master.zip
Archive:  master.zip
c590641febf4d03e89c46f8e7ef4c3fb2a455520
   creating: neovim-master/
  inflating: neovim-master/.cirrus.yml  
  inflating: neovim-master/.clang-format  
...
  inflating: neovim-master/test/unit/viml/expressions/parser_spec.lua  
  inflating: neovim-master/test/unit/viml/expressions/parser_tests.lua  
  inflating: neovim-master/test/unit/viml/helpers.lua

Navigeer naar de uitgepakte neovim map om onze tutorial te starten.

dany@pindabook:~> cd neovim-master/ && ls
BACKERS.md   ci     cmake.config  CMakeLists.txt   CMakePresets.json  CONTRIBUTING.md  MAINTAIN.md  README.md  scripts  src
BSDmakefile  cmake  cmake.deps    cmake.packaging  contrib            LICENSE.txt      Makefile     runtime    snap     test

De inhoud van de hoofdmap toont markdown-bestanden (.md), tekstbestanden (.txt), en een JSON-bestand.

Ack instellen

Aangezien de meeste zoekopdrachten vanuit het Linux terminalvenster leiden tot oncontroleerbaar scrollen vanwege enorme hoeveelheden zoekresultaten, kunnen we deze zoekresultaten naar less sturen om de resultaten die de normale grootte van het terminalvenster overschrijden gebruiksvriendelijk weer te geven.

dany@pindabook:~/neovim-master> echo '--pager=less -RFX' >> ~/.ackrc

De bovenstaande ack-configuratieopdracht handelt op intelligente wijze de overlopende resultaten af.

Totaal aantal bestanden weergeven

Dit eerste opdrachtvoorbeeld helpt ons de logische efficiëntie van zoeken met ack te onderscheiden van zoeken met find. Via find kunnen we het totaal aantal bestanden in het neovim-project achterhalen met de volgende opdracht:

dany@pindabook:~/neovim-master> find . | wc -l
3287

Ack telt alleen bestanden die het relevant acht, vandaar dat het resultaat anders is.

dany@pindabook:~/neovim-master> ack -f | wc -l
3093

De bovengenoemde 6% (3287-3093) genegeerde bestanden worden bij alle ack-zoekopdrachten genegeerd.

Op zoek naar een tekstfragment in een map vol bestanden

Laten we proberen om de aanwezigheid van het tekstpatroon "restrict" op te vragen.

dany@pindabook:~/neovim-master> ack restrict

Ack

De bovenstaande uitvoer toont de exacte regelnummers in de bestanden die het overeenkomstig tekstpatroon bevatten. In de uitgevoerde resultaten zijn ook delen van woorden als restricted en restriction te vinden.

Op zoek naar een woord in een map vol bestanden

Als je niet geïnteresseerd bent in een zoekresultaat als variatie maar als volledig woord, moet je dit aangeven met de -w (--word-regexp) optie.

dany@pindabook:~/neovim-master> ack -w restrict
cmake.deps/cmake/GettextCMakeLists.txt:102:string(REPLACE "#undef restrict" "#define restrict __restrict" CONFIG_CONTENT ${CONFIG_CONTENT})
test/symbolic/klee/nvim/memory.c:89:char *xstpcpy(char *restrict dst, const char *restrict src)
test/symbolic/klee/nvim/garray.c:161:void ga_concat(garray_T *gap, const char_u *restrict s)
test/symbolic/klee/nvim/garray.c:167:  ga_concat_len(gap, (const char *restrict) s, strlen((char *) s));
test/symbolic/klee/nvim/garray.c:175:void ga_concat_len(garray_T *const gap, const char *restrict s,
LICENSE.txt:249:	  add.  The changes and their license must not restrict others from
src/clint.py:84:      Specify a number 0-5 to restrict errors to certain verbosity levels.
src/klib/kvec.h:164:static inline void *_memcpy_free(void *const restrict dest, void *const restrict src,
...

Zoals je ziet, zoekt ack naar restrict als volledig woord en niet als deel van een ander woord.

Op zoek naar een tekstfragment in een bepaald type bestanden

Misschien wil je enkel zoeken in bestanden met een specifiek bestandstype, zoals een Python (--python) bestand, c (--c) bestand, vim (--vim) bestand of een ander bestandstype.

dany@pindabook:~/neovim-master> ack -w --python restrict
src/clint.py:84:      Specify a number 0-5 to restrict errors to certain verbosity levels.

Deze opdracht zoekt enkel in python bestanden naar het woord restrict en vond een overeenkomst in regel 84 van het bestand src/clint.py.

Tel het aantal gevonden overeenkomsten in elk bestand

Aangezien de uitgepakte neovim-broncodemap die wij gebruiken verschillende bestandstypen heeft, telt de volgende opdracht het voorkomen van een specifiek zoekpatroon (restrict) in elk van deze bestandstypen.

dany@pindabook:~/neovim-master> ack -c restrict
BSDmakefile:0
.gitattributes:0
.styluaignore:0
.stylua.toml:0
contrib/flake.lock:0
contrib/luarc.json:0
contrib/flake.nix:0
contrib/asan.sh:0
contrib/gdb/neovim_gdb.vim:0
contrib/gdb/nvim-gdb-pretty-printers.py:0
contrib/local.mk.example:0
...

Hoeveel overeenkomsten werden er gevonden?

De uitvoer van vorige opdracht bevat bestanden met nul overeenkomsten voor het opgegeven tekstpatroon. Om dat te voorkomen, toont de volgende opdracht het totaal aantal bestandsregels dat overeenkomt met het gespecificeerde tekstpatroon.

dany@pindabook:~/neovim-master> ack -ch restrict
238

Wil je enkel het aantal regels waar het woord restrick in python bestanden voorkomt:

dany@pindabook:~/neovim-master> ack -ch -w --python restrict
1

Met de time opdracht kunnen we de snelheid van onze zoekopdrachten controleren:

dany@pindabook:~/neovim-master> time ack -ch restrict
238

real    0m0,341s
user    0m0,288s
sys     0m0,052s

Door meer specifiek te zijn in onze zoekpatrooncriteria, krijgen we een snellere uitvoer:

dany@pindabook:~/neovim-master> time ack -ch -w --python restrict
1

real    0m0,196s
user    0m0,172s
sys     0m0,024s

Met de volgende opdracht worden enkel de bestanden waarin het zoekpatroon voorkomt weergegeven:

dany@pindabook:~/neovim-master> ack -f --python
contrib/gdb/nvim-gdb-pretty-printers.py
scripts/shadacat.py
scripts/gen_vimdoc.py
src/clint.py
src/nvim/testdir/pyxfile/py3_magic.py
src/nvim/testdir/pyxfile/py3_shebang.py
src/nvim/testdir/pyxfile/pyx.py
src/nvim/testdir/pyxfile/py2_magic.py
src/nvim/testdir/pyxfile/py2_shebang.py
src/nvim/testdir/test_makeencoding.py

Het ack-zoekpatroon kan ook gericht zijn op de bestandsnaam. Elk C-bestand met log kan worden gevonden met de volgende opdracht:

dany@pindabook:~/neovim-master> ack -g log --cc
src/nvim/log.c
src/nvim/log.h

De ack zoekopdracht is zeer flexibel wanneer het in een map met broncode wordt gebruikt. Maar ook voor bestanden binnen een Linux-omgeving. Het is uitbreidbaar en snel. Gebruik de opdracht man ack om meer opties te vinden om dit snelle en lichte gereedschap te verkennen.

Opruimen

Om straks de testmap met de neovim broncode te kunnen verwijderen, verlaten we de map:

dany@pindabook:~/neovim-master> cd

Verwijder zowel de bronmap als het gedownloade archief:

dany@pindabook:~> rm -r neovim-master/
dany@pindabook:~> rm master.zip

Verwijder tenslotte de ack opdracht en alle bijhorende en niet langer noodzakelijke afhankelijke pakketten:

dany@pindabook:~> sudo zypper remove -u ack
[sudo] wachtwoord voor root: 
Lezen van geïnstalleerde pakketten...
Pakketafhankelijkheden oplossen...

De volgende 3 pakketten zullen worden VERWIJDERD:
  ack perl-App-Ack perl-File-Next

3 te verwijderen pakketten.
Na de bewerking zal 229,0 KiB worden vrijgemaakt.
Doorgaan? [j/n/v/...? alle opties tonen] (j): 
(1/3) Verwijderen van ack-3.5.0-bp154.1.15.noarch .............................................................................[gereed]
(2/3) Verwijderen van perl-App-Ack-3.5.0-bp154.1.15.noarch ....................................................................[gereed]
(3/3) Verwijderen van perl-File-Next-1.18-bp154.1.59.x86_64 ...................................................................[gereed]