This shows you the differences between two versions of the page.
uso:laboratoare:laborator-06:inspect-files [2022/11/08 16:41] alexandru.vladut02 [Căutarea în fișiere] |
uso:laboratoare:laborator-06:inspect-files [2023/11/07 19:27] (current) maria_irina.gherman [Căutarea în fișiere] |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Inspectarea fișierelor ====== | ====== Inspectarea fișierelor ====== | ||
- | ===== Inspectarea rapida a conținutului fișierelor ===== | + | ===== Inspectarea rapidă a conținutului fișierelor ===== |
- | În secțiunea anterioară, ''%%Inspectarea sistemului de fișiere%%'', am văzut cum căutăm fișiere în sistem cu ajutorul utilitarelor ''%%locate%%'' și ''%%find%%''. Căutăm un fișier cu un scop: vrem să găsim fișierul ''%%README%%'' pentru informații despre compilarea proiectului, vrem să ne amintim un detaliu de implementare din cod, etc. | + | În secțiunea anterioară, ''%%Inspectarea sistemului de fișiere%%'', am văzut cum căutăm fișiere în sistem cu ajutorul utilitarului ''%%find%%''. Căutăm un fișier cu un scop: vrem să găsim fișierul ''%%README%%'' pentru informații despre compilarea proiectului, vrem să ne amintim un detaliu de implementare din cod, etc. |
De cele mai multe ori acțiunea noastră se poate grupa în una din următoarele două categorii: | De cele mai multe ori acțiunea noastră se poate grupa în una din următoarele două categorii: | ||
- | * Ne dorim să inspectăm rapid conținutul fișierelor pentru a ne da seama dacă am găsit informația căutată. | + | * Ne dorim să inspectăm/citim rapid conținutul fișierelor pentru a ne da seama dacă am găsit informația căutată. |
- | * Ne dorim să afișăm pe ecran conținutul fișierelor pentru a extrage și prelucra informații din acestea. | + | * Ne dorim să afișăm pe ecran conținutul fișierelor pentru a extrage și prelucra informații din acestea cu ajutorul altor comenzi. |
==== Căutarea informației într-un fișier ==== | ==== Căutarea informației într-un fișier ==== | ||
- | Pentru a vedea rapid conținutul unui fișier folosim utlitarul ''%%less%%''. | + | Pentru a vedea rapid conținutul unui fișier folosim utilitarul ''%%less%%''. |
<note> | <note> | ||
Line 73: | Line 73: | ||
=== Exerciții === | === Exerciții === | ||
- | - Analizați, folosind ''%%less%%'', algoritmul de căutare din fișierul ''%%workspace/C/searching/linear_search.c%%''. Ce implementare este mai eficientă: **binary_search** sau **linear_search**? | + | - Analizați, folosind ''%%less%%'', algoritmii de căutare din fișierele ''%%workspace/C/searching/linear_search.c%%'' și ''%%workspace/C/searching/binary_search.c%%''. Ce implementare este mai eficientă: **binary_search** sau **linear_search**? |
- | - Analizați, folosind ''%%less%%'', algoritmul de sortare **quick_sort**. Folosiți utilitarul ''%%find%%'' pentru a găsi fișierul sursă care conține implementarea. | + | - Folosiți utilitarul ''%%find%%'' pentru a găsi fișierul sursă care conține algoritmul de sortare **quick_sort**. Analizați implementarea acestuia folosind utilitarul ''%%less%%''. |
- | - Analizați, folosind ''%%less%%'', algoritmul de sortare **merge_sort**. Folosiți utilitarul ''%%find%%'' pentru a găsi fișierul sursă care conține implementarea. | + | - Folosiți utilitarul ''%%find%%'' pentru a găsi fișierul sursă care conține algoritmul de sortare **merge_sort**. Analizați implementarea acestuia folosind utilitarul ''%%less%%''. |
- Căutați pe Google detalii despre cei doi algoritmi de sortare și încercați să vă răspundeți la întrebarea: Când folosim **merge_sort** și când folosim **quick_sort**? | - Căutați pe Google detalii despre cei doi algoritmi de sortare și încercați să vă răspundeți la întrebarea: Când folosim **merge_sort** și când folosim **quick_sort**? | ||
Line 100: | Line 100: | ||
Observăm că pentru un fișier cu un număr mare de linii, așa cum este **binary_search.c**, afișarea întregului conținut pe ecran devine un impediment în a putea înțelege și urmări conținutul. De aceea vă încurajăm să folosiți ''%%less%%'' în loc de ''%%cat%%'' pentru a inspecta un fișier: vă este mult mai ușor să vă plimbați în interiorul fișierului și puteți folosi funcția search pentru a căuta în fișier. De asemeni, folosind ''%%less%%'' vă păstrați consola curată și puteți urmări mai ușor ce comenzi ați dat anterior și care au fost rezultatele acestora. | Observăm că pentru un fișier cu un număr mare de linii, așa cum este **binary_search.c**, afișarea întregului conținut pe ecran devine un impediment în a putea înțelege și urmări conținutul. De aceea vă încurajăm să folosiți ''%%less%%'' în loc de ''%%cat%%'' pentru a inspecta un fișier: vă este mult mai ușor să vă plimbați în interiorul fișierului și puteți folosi funcția search pentru a căuta în fișier. De asemeni, folosind ''%%less%%'' vă păstrați consola curată și puteți urmări mai ușor ce comenzi ați dat anterior și care au fost rezultatele acestora. | ||
- | Folosim comanda ''%%cat%%'' în combinație cu alte comenzi pentru a extrage sau filtra conținutul anumitor fișiere. Comanda ''%%cat%%'' primește ca argumente calea către unul sau mai multe fișiere și afișează pe ecran conținutul concatenat al acestora. | + | Folosim comanda ''%%cat%%'' în combinație cu alte comenzi pentru a extrage sau filtra conținutul anumitor fișiere. Comanda ''%%cat%%'' primește ca argument calea către unul sau mai multe fișiere și afișează pe ecran conținutul concatenat al acestora. |
Un exemplu uzual este faptul că vrem să extragem informațiile despre starea memoriei sistemului din fișierul ''%%/proc/meminfo%%''. Pentru aceasta rulăm comanda de mai jos: | Un exemplu uzual este faptul că vrem să extragem informațiile despre starea memoriei sistemului din fișierul ''%%/proc/meminfo%%''. Pentru aceasta rulăm comanda de mai jos: | ||
Line 110: | Line 110: | ||
MemAvailable: 874420 kB | MemAvailable: 874420 kB | ||
</code> | </code> | ||
- | În exemplul de mai sus folosim ''%%cat%%'' pentru a oferi ca intrare conținutul fișierului ''%%/proc/meminfo%%'' utilitarului ''%%grep%%''; cu utilitarul ''%%grep%%'' filtrăm conținutul după textul ''%%"Mem"%%''. Cu alte cuvinte, outputul comenzii ''%%cat /proc/meminfo%%'', adică conținutul fișierului ''%%/proc/meminfo%%'' este textul pe care utilitarul ''%%grep%%'' îl prelucrează. | + | În exemplul de mai sus folosim ''%%cat%%'' pentru a oferi ca intrare conținutul fișierului ''%%/proc/meminfo%%'' utilitarului ''%%grep%%''; cu utilitarul ''%%grep%%'' filtrăm conținutul după textul ''%%"Mem"%%''. Despre operatorul ''%%|%%'' vom vorbi mai jos. |
+ | |||
+ | Cu alte cuvinte, outputul comenzii ''%%cat /proc/meminfo%%'', adică conținutul fișierului ''%%/proc/meminfo%%'' este textul pe care utilitarul ''%%grep%%'' îl prelucrează. | ||
**Exercițiu**: Plecând de la exemplul de mai sus, extrageți din fișierul ''%%/proc/cpuinfo%%'' dimensiunea memoriei cache a procesorului vostru; filtrați conținutul după textul ''%%"cache"%%''. | **Exercițiu**: Plecând de la exemplul de mai sus, extrageți din fișierul ''%%/proc/cpuinfo%%'' dimensiunea memoriei cache a procesorului vostru; filtrați conținutul după textul ''%%"cache"%%''. | ||
Line 169: | Line 171: | ||
În acest moment am găsit răspunsul căutat, dar avem două mici neajunsuri: | În acest moment am găsit răspunsul căutat, dar avem două mici neajunsuri: | ||
- | * Ne lipsește antetul, așa că nu știm ce informații avem pe coloane | + | * Ne lipsește antetul (aflat pe prima linie), așa că nu știm ce informații avem pe coloane |
* Procesele sunt sortate crescător, a.î. cel mai consumator este ultimul; vrem să fie sortate descrescător | * Procesele sunt sortate crescător, a.î. cel mai consumator este ultimul; vrem să fie sortate descrescător | ||
Line 208: | Line 210: | ||
===== Căutarea în fișiere ===== | ===== Căutarea în fișiere ===== | ||
- | Așa cum am văzut până în acest punct din carte, majoritatea comenzilor Linux afișează o gamă largă de informații pe care apoi utilizatorul (adică noi) le filtrează pentru a extrage ceea ce îl intresează. La începutul acestei secțiuni, dar și de-a lungul cărții, am folosit utilitarul ''%%grep%%'' ca să filtrăm rezultatul unei comenzi. | + | Așa cum am văzut până în acest punct, majoritatea comenzilor Linux afișează o gamă largă de informații pe care apoi utilizatorul (adică noi) le filtrează pentru a extrage ceea ce îl interesează. La începutul acestui laborator, dar și de-a lungul materiei, am folosit utilitarul ''%%grep%%'' ca să filtrăm rezultatul unei comenzi. |
- | Comanda ''%%grep%%'' este una dintre cele mai folosite în linie de comandă. Sintaxa de folosire a ''%%grep%%'' este următoarea: | + | Comanda ''%%grep%%'' este una dintre cele mai folosite în linia de comandă. Sintaxa de folosire a ''%%grep%%'' este următoarea: |
<code bash> | <code bash> | ||
Line 249: | Line 251: | ||
==== Exerciții ==== | ==== Exerciții ==== | ||
- | - Căutați //patternul// "l" în fișierul ''%%binary_search.c%%'', pentru a vedea unde este folosit parametrul **left**. Observați cât de multe rezultate irelevante ați găsit datorită faptului că am căutat doar caracterul **l**. Aici există o lecție de învățat. Numele variabilelor sunt foarte improtante: nu fac doar codul mai ușor de înțeles, dar ajută și căutarea. Folosiți //patternul// "param l" în încercarea de a restrânge căutarea. | + | - Căutați //patternul// "l" în fișierul ''%%binary_search.c%%'', pentru a vedea unde este folosit parametrul **left**. Observați cât de multe rezultate irelevante ați găsit datorită faptului că am căutat doar caracterul **l**. Aici există o lecție de învățat. Numele variabilelor sunt foarte importante: nu fac doar codul mai ușor de înțeles, dar ajută și căutarea. Folosiți //patternul// "param l" în încercarea de a restrânge căutarea. |
- Căutați //patternul// "arr" în fișierul ''%%binary_search.c%%''. | - Căutați //patternul// "arr" în fișierul ''%%binary_search.c%%''. | ||
- Căutați //patternul// "binarysearch1" în fișierul ''%%binary_search.c%%'' pentru a vedea cum este apelată funcția de căutare. | - Căutați //patternul// "binarysearch1" în fișierul ''%%binary_search.c%%'' pentru a vedea cum este apelată funcția de căutare. | ||
- | ==== Opțiuni uzuale ale grep ==== | + | ==== Extra: Opțiuni uzuale ale grep ==== |
- | === Afișarea numărului liniei care conține patternul === | + | === Afișarea numărului liniei care conține pattern-ul === |
- | Folosim opțiunea ''%%-n%%'' pentru a afișa și numărul liniei care conține patternul căutat: | + | Folosim opțiunea ''%%-n%%'' pentru a afișa și numărul liniei care conține pattern-ul căutat: |
<code bash> | <code bash> | ||
Line 308: | Line 310: | ||
=== Căutarea recursivă a unui pattern === | === Căutarea recursivă a unui pattern === | ||
- | În căutările noastre de până acum, ca și în exemplele de mai sus, am presupus că știm în ce fișiere se găsește informația căutată de noi. Acest lucru este adevărat pentru fișiere din sistem cu informații bine cunoscute, cum ar fi ''%%/proc/meminfo%%'', dar atunci când lucrăm cu un proiect nou nu vom ști în ce fișiere să căutăm informația dorită. De exemplu, în cazul proiectului cu algoritmi implementați în C, noi am făcut presupunerea că vom găsi linii care conțin patternul **search** în fișierul ''%%workspace/C/searching/binary_search.c%%''. | + | În căutările noastre de până acum, ca și în exemplele de mai sus, am presupus că știm în ce fișiere se găsește informația căutată de noi. Acest lucru este adevărat pentru fișiere din sistem cu informații bine cunoscute, cum ar fi ''%%/proc/meminfo%%'', dar atunci când lucrăm cu un proiect nou, nu vom ști în ce fișiere să căutăm informația dorită. De exemplu, în cazul proiectului cu algoritmi implementați în C, noi am făcut presupunerea că vom găsi linii care conțin patternul **search** în fișierul ''%%workspace/C/searching/binary_search.c%%''. |
- | Atunci când nu știm în ce fișiere se află informația căutată putem să-i spunem lui ''%%grep%%'' să caute recursiv prin toată ierarhia de fișiere dintr-un anumit director. Pentru a efectua o căutare recursivă folosim opțiunea ''%%-r%%'', ca în exemplul de mai jos: | + | Atunci când nu știm în ce fișiere se află informația căutată, putem să-i spunem lui ''%%grep%%'' să caute recursiv prin toată ierarhia de fișiere dintr-un anumit director. Pentru a efectua o căutare recursivă folosim opțiunea ''%%-r%%'', ca în exemplul de mai jos: |
<code bash> | <code bash> | ||
Line 393: | Line 395: | ||
- Găsiți toate aparițiile patternului ''%%binarySearch%%''. | - Găsiți toate aparițiile patternului ''%%binarySearch%%''. | ||
- Găsiți toate aparițiile patternului ''%%quickSort%%''. | - Găsiți toate aparițiile patternului ''%%quickSort%%''. | ||
- | |||
- | ===== Compararea fișierelor ===== | ||
- | |||
- | Atunci când lucrăm cu fișiere o să ne întâlnim sporadic cu nevoia de a compara două fișiere între ele. | ||
- | |||
- | ==== Compararea octet cu octet ==== | ||
- | |||
- | Compararea octet cu octet este utilă atunci când vrem aflăm dacă două fișiere sunt diferite sau nu, dar nu ne interesează cu ce diferă. Un exemplu ar fi: avem o arhivă cu aceelași nume în două locații diferite și nu mai ținem minte dacă am copiat-o noi sau este o coincidență de nume. Verificăm, fără să fie nevoie să le dezarhivăm, printr-o comparare la nivel de octet folosind comanda ''%%cmp%%'': | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ cmp Documents/uso.tar Downloads/uso.tar | ||
- | student@uso:~$ cmp Downloads/courses.tar Downloads/uso.tar | ||
- | Downloads/courses.tar Downloads/uso.tar differ: byte 1, line 1 | ||
- | </code> | ||
- | În exemplul de mai sus, observăm că arhiva din calea ''%%Documents/uso.tar%%'' și cea din calea ''%%Downloads/uso.tar%%'' sunt identice, pe când arhivele ''%%Downloads/courses.tar%%'' și ''%%Downloads/uso.tar%%'' diferă de la primul octet //(byte 1, line 1)//. Observăm că în cazul în care fișierele sunt identice, ''%%cmp%%'' nu afișează nimic pe ecran. | ||
- | |||
- | ==== Compararea text ==== | ||
- | |||
- | Putem folosi ''%%cmp%%'' pentru a compara orice tip de fișier, inclusiv fișiere text, ca în exemplul de mai jos: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ cmp workspace/C/sorting/merge_sort.c workspace/C/sorting/quick_sort.c | ||
- | workspace/C/sorting/merge_sort.c workspace/C/sorting/quick_sort.c differ: byte 1, line 1 | ||
- | </code> | ||
- | Rezultatul de mai sus nu este ideal: știm că cele două fișiere sunt diferite, dar nu știm și cu ce anume diferă. Pentru comparații text folosim utilitarul ''%%diff%%''. | ||
- | |||
- | Pentru a exemplifica, navigăm în directorul ''%%~/workspace/C/sorting/%%'', facem o copie fișierului ''%%quick_sort.c%%'' cu numele ''%%quick_sort_old.c%%'' și adăugăm comentariul ''%%// It's so simple to diff%%'': | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ cd workspace/C/sorting/ | ||
- | student@uso:~/workspace/C/sorting$ cp quick_sort.c quick_sort_old.c | ||
- | student@uso:~/workspace/C/sorting$ echo "// It's so simple to diff" >> quick_sort.c | ||
- | </code> | ||
- | Folosim comanda ''%%diff%%'' pentru a vedea diferențele dintre ''%%quick_sort.c%%'' și ''%%quick_sort_old.c%%'': | ||
- | |||
- | <code bash> | ||
- | student@uso:~/workspace/C/sorting$ diff quick_sort.c quick_sort_old.c | ||
- | 98d97 | ||
- | < // It's so simple to diff | ||
- | student@uso:~/workspace/C/sorting$ diff quick_sort_old.c quick_sort.c | ||
- | 97a98 | ||
- | > // It's so simple to diff | ||
- | </code> | ||
- | Observăm următorul lucru: linia care diferă este precedată de caracterul ''%%<%%'' atunci când provine din primul fișier, și este precedată de caracterul ''%%>%%'' atunci când provine din al doilea fișier. | ||
- | |||
- | === Exerciții === | ||
- | |||
- | - TODO | ||