This shows you the differences between two versions of the page.
uso:laboratoare:laborator-07:inspect-fs [2021/11/16 00:09] mihai_daniel.soare [Căutarea unui fișier în sistem] |
uso:laboratoare:laborator-07:inspect-fs [2021/11/22 16:46] (current) andreia.ocanoaia [Selectarea multiplor fișiere folosind globbing] |
||
---|---|---|---|
Line 70: | Line 70: | ||
)). | )). | ||
- | ==== Interpretarea paginii de manual ==== | ||
- | La o primă vedere, textul paginii de manual poate fi intimidant; unele utilitare au mai multe opțiuni și argumente, unele opționale, altele nu. O să trecem prin sintaxă și o să vedem că lucrurile sunt mult mai simple decât par. Să analizăm pagina de manual a utilitarului ''%%ls%%''; ''%%man ls%%'': | + | ===== Selectarea multiplor fișiere folosind globbing ===== |
- | <code bash> | ||
- | LS(1) User Commands LS(1) | ||
- | |||
- | NAME | ||
- | ls - list directory contents | ||
- | |||
- | SYNOPSIS | ||
- | ls [OPTION]... [FILE]... | ||
- | |||
- | DESCRIPTION | ||
- | List information about the FILEs (the current directory by default). | ||
- | Sort entries alphabetically if none of -cftuvSUX nor --sort is speci‐ | ||
- | fied. | ||
- | |||
- | Mandatory arguments to long options are mandatory for short options | ||
- | too. | ||
- | |||
- | -a, --all | ||
- | do not ignore entries starting with . | ||
- | |||
- | -A, --almost-all | ||
- | do not list implied . and .. | ||
- | |||
- | --author | ||
- | Manual page ls(1) line 1 (press h for help or q to quit) | ||
- | </code> | ||
- | |||
- | * Prima secțiune care ne interesează este "DESCRIPTION". Citim descrierea și ne dăm seama dacă utilitarul ne va ajuta în rezolvarea sarcinii pe care o avem. În cazul utilitarului ''%%ls%%'', descrierea ne informează că acesta afișează informații despre fișierele din calea indicată, sau din directorul curent atunci când nu specificăm o cale. | ||
- | * Cea de-a doua secțiune care ne interesează este "SYNOPSIS". Aceasta ne spune cum putem să rulăm utilitarul, ce opțiuni și argumente sunt opționale (pot lipsi) și ce opțiuni și argumente sunt obligatorii. | ||
- | |||
- | <code bash> | ||
- | SYNOPSIS | ||
- | ls [OPTION]... [FILE]... | ||
- | </code> | ||
- | |||
- | Sintaxa **[ ]** ne spune că acea categorie este opțională. Astfel, pentru ''%%ls%%'', deducem că atât opțiunile (''%%[OPTION]...%%'') cât și argumentele (''%%[FILE]...%%'', calea către fișiere sau directoare) sunt opționale. Cele trei puncte ''%%...%%'' înseamnă mai multe din categoria precedentă: deci ''%%[OPTION]...%%'' înseamnă că nu suntem limitați la o singură opțiune, dar opțiunile pot să și lipsească în totalitate datorită **[ ]**. | ||
- | |||
- | O comandă poate avea atât opțiuni, cât și argumente. Opțiunile îi spun unei comenzi cum să își modifice comportamentul, și de obicei sunt precedate de ''%%-%%'' (ex. ''%%-l%%'', ''%%--verbose%%'', etc.). Argumentele îi spun unei comenzi pe ce să acționeze. | ||
- | |||
- | În exemplul de mai jos: | ||
- | <code bash> | ||
- | student@uso:~$ ls -l Desktop/ | ||
- | </code> | ||
- | Avem utilitarul ''%%ls%%'' care primește opțiunea ''%%-l%%'' și argumentul ''%%Desktop/%%''. | ||
- | |||
- | * Ultima observație pe care o facem este că opțiunile unei comenzi pot avea o formă prescurtată, ''%%-a%%'', sau o formă lungă, ''%%--all%%''. Nu este obligatoriu ca o opțiune să expună ambele forme, deși majoritatea o fac. Opțiunile în formă prescurtată pot fi concatenate și precedate de un singur ''%%-%%'', ca în exemplul de mai jos: | ||
- | <code bash> | ||
- | student@uso:~$ ls -la Desktop/ | ||
- | </code> | ||
- | |||
- | === Exerciții === | ||
- | |||
- | Deschideți pagina de manual a utilitarului ''%%ls%%''. | ||
- | |||
- | - Căutați opțiunea ''%%-a%%''. Rulați comanda ''%%ls -a%%''. | ||
- | - Căutați opțiunea ''%%-d%%''. Rulați comanda ''%%ls -d%%''. | ||
- | - Căutați opțiunea ''%%-F%%''. Rulați comanda ''%%ls -F%%''. | ||
- | - Căutați cuvântul cheie ''%%list%%''. Treceți la următoarea apariție a cuvântului cheie până ajungeți la opțiunea ''%%-l%%''. | ||
- | - Mergeți la finalul paginii folosind tasta ''%%G%%''. Căutați cuvântul cheie ''%%color%%'' până ajungeți la opțiunea ''%%--color%%'' (Hint: ''%%?%%''). | ||
- | |||
- | |||
- | ==== Utilizarea pachetului tldr ==== | ||
- | |||
- | Utilitarul ''%%tldr%%'' (too long, didn't read) oferă o versiune simplificată a paginilor de manual. Acesta ne va arăta un rezumat al utilizării unei comenzi cu opțiunile cele mai des folosite în comunitate. | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ tldr ls | ||
- | ls | ||
- | List directory contents. | ||
- | |||
- | - List files one per line: | ||
- | ls -1 | ||
- | |||
- | - List all files, including hidden files: | ||
- | ls -a | ||
- | |||
- | - Long format list (permissions, ownership, size and modification date) of all files: | ||
- | ls -la | ||
- | |||
- | - Long format list with size displayed using human readable units (KB, MB, GB): | ||
- | ls -lh | ||
- | |||
- | - Long format list sorted by size (descending): | ||
- | ls -lS | ||
- | |||
- | - Long format list of all files, sorted by modification date (oldest first): | ||
- | ls -ltr | ||
- | </code> | ||
<note> | <note> | ||
- | + | Înainte de a trece mai departe, mergeți în directorul ''%%~/uso-lab/labs/05-cli/support/support-globbing%%''. | |
- | + | ||
- | Acesta trebuie tratat ca un cheatsheet accesibil din linie de comandă. ''%%tldr%%'' nu elimină utilizarea paginilor ''%%man%%'', dar ne ajută să găsim rapid opțiunile uzuale. Acestea fiind spuse, vă recomandăm ca întotdeaună să citiți și să înțelegeți din paginile ''%%man%%'' ce efect au opțiunile unei comenzi înainte de a le folosi. Feriți-vă să rulați comenzi orbește, pentru că așa ați găsit pe StackOverflow, tldr, etc. Întotdeauna asigurați-vă că ați înțeles cum și de ce rulați comanda și abia apoi treceți la fapte. | + | |
</note> | </note> | ||
- | |||
- | === Exerciții: Utilizarea pachetului tldr === | ||
- | |||
- | Instalați pachetul ''%%tldr%%'' pe mașina voastră. | ||
- | |||
- | - Accesați pagina ''%%tldr%%'' a utilitarului ''%%ls%%''. | ||
- | - Accesați pagina ''%%tldr%%'' a utilitarului ''%%zip%%''. | ||
- | - Accesați pagina ''%%tldr%%'' a utilitarului ''%%tar%%''. | ||
- | - Accesați pagina ''%%tldr%%'' a utilitarului ''%%git%%''. | ||
- | - Accesați pagina ''%%tldr%%'' a utilitarului ''%%man%%''. | ||
- | |||
- | ===== Selectarea multiplor fișiere folosind globbing ===== | ||
Întotdeauna când deschidem un terminal o facem pentru că vrem să realizăm o sarcină: de exemplu, vrem să redenumim rapid ultimele poze făcute cu telefonul de la genericul **DCIM1001** la ceva util **Excursie Sinaia, Ian 2020, 1001**, vrem să ne testăm proiectul și să urcăm modificările pe GitHub, etc. | Întotdeauna când deschidem un terminal o facem pentru că vrem să realizăm o sarcină: de exemplu, vrem să redenumim rapid ultimele poze făcute cu telefonul de la genericul **DCIM1001** la ceva util **Excursie Sinaia, Ian 2020, 1001**, vrem să ne testăm proiectul și să urcăm modificările pe GitHub, etc. | ||
Line 187: | Line 84: | ||
<code bash> | <code bash> | ||
- | student@uso:~/Pictures$ mv DCIM* excursie-Sinaia-2020/ | + | student@uso:~/.../05-cli/support/support-globbing$ mv DCIM* excursie-Sinaia-2020/ |
</code> | </code> | ||
Observăm argumentul pe care l-am dat comenzii ''%%mv%%'', și anume ''%%DCIM*%%''. Expresia ''%%DCIM*%%'' este un exemplu de globbing: adică o expresie care descrie un tipar prin folosirea unor caractere speciale, așa cum este caracterul ''%%*%%''. În cazul de față, expresia ''%%DCIM*%%'' înseamnă orice fișier al cărui nume începe cu șirul de caractere ''%%DCIM%%''. | Observăm argumentul pe care l-am dat comenzii ''%%mv%%'', și anume ''%%DCIM*%%''. Expresia ''%%DCIM*%%'' este un exemplu de globbing: adică o expresie care descrie un tipar prin folosirea unor caractere speciale, așa cum este caracterul ''%%*%%''. În cazul de față, expresia ''%%DCIM*%%'' înseamnă orice fișier al cărui nume începe cu șirul de caractere ''%%DCIM%%''. | ||
Line 208: | Line 105: | ||
Observăm că în expresia ''%%D*%%'', caracterul ''%%*%%'' înglobează toate caracterele care urmează literei **D**: "esktop", "ocuments" și "ownloads". Observăm că în cazul expresie ''%%Music*%%'', ''%%*%%'' nu ține locul nici unui caracter. | Observăm că în expresia ''%%D*%%'', caracterul ''%%*%%'' înglobează toate caracterele care urmează literei **D**: "esktop", "ocuments" și "ownloads". Observăm că în cazul expresie ''%%Music*%%'', ''%%*%%'' nu ține locul nici unui caracter. | ||
- | ==== Caracterul special ? ==== | ||
- | |||
- | În sintaxa globbing, caracterul ''%%?%%'' înlocuiește exact un caracter, oricare ar fi acela. În directorul nostru home (''%%~%%''), executăm următoarele comenzi: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ ls -d Musi? | ||
- | Music | ||
- | |||
- | student@uso:~$ ls -d Mus?? | ||
- | Music | ||
- | |||
- | student@uso:~$ ls -d Music? | ||
- | ls: cannot access 'Music?': No such file or directory | ||
- | </code> | ||
- | Observăm că expresiile ''%%Musi?%%'' și ''%%Mus??%%'' s-au înlocuit cu succes cu numele directorului ''%%Music%%'', dar expresia ''%%Music?%%'' a generat o eroare deoarece nu există nici un fișier **Music** urmat de un caracter. | ||
==== Sintaxa specială [] ==== | ==== Sintaxa specială [] ==== | ||
Line 252: | Line 134: | ||
<code bash> | <code bash> | ||
- | student@uso:~/Pictures$ mv DCIM[0-9][0-9][0-9][0-9].jpg excursie-Sinaia-2020/ | + | student@uso:~/.../05-cli/support/support-globbing$ mv DCIM[0-9][0-9][0-9][0-9].jpg excursie-Sinaia-2020/ |
</code> | </code> | ||
Cu expresia de mai sus vom muta toate pozele din intervalul **DCIM0000** - **DCIM9999**. | Cu expresia de mai sus vom muta toate pozele din intervalul **DCIM0000** - **DCIM9999**. | ||
Line 298: | Line 180: | ||
De multe ori ne aflăm în situația în care căutăm un fișier pe disc: ex. doar ce am clonat un proiect de pe GitHub și vrem să inspectăm fișierul **Makefile** pentru a vedea cum compilăm și rulăm proiectul. Un alt exemplu poate fi că vrem să vedem cum arată fișierele de test existente în proiect. De multe ori, ințelegem mai bine proiectul doar prin simpla inspectare a testelor. | De multe ori ne aflăm în situația în care căutăm un fișier pe disc: ex. doar ce am clonat un proiect de pe GitHub și vrem să inspectăm fișierul **Makefile** pentru a vedea cum compilăm și rulăm proiectul. Un alt exemplu poate fi că vrem să vedem cum arată fișierele de test existente în proiect. De multe ori, ințelegem mai bine proiectul doar prin simpla inspectare a testelor. | ||
- | Există două utilitare care ne permit să căutăm în cadrul sistemului de fișiere: ''%%locate%%'' și ''%%find%%''. | + | Există două utilitare care ne permit să căutăm în cadrul sistemului de fișiere: ''%%locate%%'' și ''%%find%%''. Ele au fost prezentate și în ''%%laboratorul 03: Lucrul cu fișiere (2)%%''. În continuare vedem câteva exemple de folosire ale utilitarului ''%%find%%''. |
- | ==== Utilitarul locate ==== | ||
- | |||
- | Utilitarul ''%%locate%%'' folosește o bază de date pentru a căuta în fișierele de pe sistem. Inspectăm pagina de manual a utilitarului pentru a vedea cum îl putem folosi, folosind comanda ''%%man%%'': | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ man locate | ||
- | |||
- | SYNOPSIS | ||
- | locate [OPTION]... PATTERN... | ||
- | </code> | ||
- | Observăm că ''%%locate%%'' primește ca argument un șir de caractere, **PATTERN**, care fac parte din numele fișierului pe care în căutăm, dar nu trebuie să-i dăm numele exact: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ locate todos.txt | ||
- | /home/student/Desktop/todos.txt | ||
- | student@uso:~$ locate todos | ||
- | /home/student/Desktop/todos.txt | ||
- | </code> | ||
- | Putem să folosim și sintaxa globbing pentru a descrie numele fișierului căutat: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ locate "*.txt" | ||
- | /home/student/vm-actions-log.txt | ||
- | /home/student/.local/lib/python2.7/site-packages/Keras_Applications-1.0.8.dist-info/top_level.txt | ||
- | /home/student/.local/lib/python2.7/site-packages/Keras_Preprocessing-1.1.2.dist-info/top_level.txt | ||
- | /home/student/.local/lib/python2.7/site-packages/Markdown-3.1.1.dist-info/entry_points.txt | ||
- | /home/student/.local/lib/python2.7/site-packages/Markdown-3.1.1.dist-info/top_level.txt | ||
- | /home/student/.local/lib/python2.7/site-packages/Werkzeug-1.0.1.dist-info/top_level.txt | ||
- | </code> | ||
- | Căutările cu ''%%locate%%'' sunt foarte rapide. Acest lucru se datorează utilizării bazei de date pentru a indexa fișierele din sistem. Într-o configurație implicită (//default//), baza de date se reconstruiește periodic, o dată la 24h. Asta înseamnă că ''%%locate%%'' nu va găsi fișiere care au fost create după reconstrucția bazei de date. Dacă vrem să reconstruim baza de date, folosim comanda ''%%updatedb%%''. | ||
- | |||
- | Hai să clonăm repository-ul **TheAlgorithms/C**. Acesta conține implementările diferitor algoritmi folosind limbajul de programare C. | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ cd workspace | ||
- | student@uso:~/workspace$ git clone https://github.com/TheAlgorithms/C.git | ||
- | student@uso:~/workspace$ cd C | ||
- | </code> | ||
- | Fiind vorba despre un repository care implementează algoritmi clasici, ne așteptăm să găsim și algoritmi de căutare, cum ar fi binary-search. Hai să căutăm după cuvântul cheie **search**. | ||
- | |||
- | <code bash> | ||
- | student@uso:~/workspace$ locate search | grep workspace/C | ||
- | student@uso:~/workspace$ | ||
- | </code> | ||
- | Observăm că nu am găsit nici un rezultat. Cum spuneam mai devreme, trebuie să reconstruim baza de date pentru a căuta în fișierele nou create. | ||
- | |||
- | <code bash> | ||
- | student@uso:~/workspace/C$ sudo updatedb | ||
- | [sudo] password for student: | ||
- | </code> | ||
- | Comanda ''%%updatedb%%'' trebuie executată în mod privilegiat, așa că folosim ''%%sudo%%''. Parola utilizatorului **student**, pe mașina noastră virtuală, este **student**. | ||
- | |||
- | <code bash> | ||
- | student@uso:~/workspace/C$ locate search | grep workspace/C | ||
- | /home/student/workspace/C/searching | ||
- | /home/student/workspace/C/data_structures/binary_trees/binary_search_tree.c | ||
- | /home/student/workspace/C/searching/CMakeLists.txt | ||
- | /home/student/workspace/C/searching/binary_search.c | ||
- | /home/student/workspace/C/searching/fibonacci_search.c | ||
- | /home/student/workspace/C/searching/interpolation_search.c | ||
- | /home/student/workspace/C/searching/jump_search.c | ||
- | /home/student/workspace/C/searching/linear_search.c | ||
- | /home/student/workspace/C/searching/modified_binary_search.c | ||
- | /home/student/workspace/C/searching/other_binary_search.c | ||
- | /home/student/workspace/C/searching/pattern_search | ||
- | /home/student/workspace/C/searching/ternary_search.c | ||
- | /home/student/workspace/C/searching/pattern_search/CMakeLists.txt | ||
- | /home/student/workspace/C/searching/pattern_search/boyer_moore_search.c | ||
- | /home/student/workspace/C/searching/pattern_search/naive_search.c | ||
- | /home/student/workspace/C/searching/pattern_search/rabin_karp_search.c | ||
- | </code> | ||
- | === Exerciții === | ||
- | |||
- | - Folosind ''%%locate%%'' căutați fișierele care conțin șirul ''%%bubble_sort%%'' în nume. | ||
- | - Folosind ''%%locate%%'' căutați fișierele care conțin șirul ''%%quick_sort%%'' în nume. | ||
- | - Folosind ''%%locate%%'' căutați fișierele care conțin șirul ''%%merge_sort%%'' în nume. | ||
- | - Folosind ''%%locate%%'' căutați fișierele care conțin șirul ''%%sort%%'' în nume. | ||
==== Utilitarul find ==== | ==== Utilitarul find ==== | ||
Line 418: | Line 223: | ||
</note> | </note> | ||
- | === Scenarii complexe de căutare === | ||
- | |||
- | Utilitarul ''%%find%%'' are o lungă listă de opțiuni pe care le putem folosi în expresii de căutare. Una din opțiunile mai cunoscute este ''%%-type%%'' care ne oferă posibilitatea de a căuta după tipul unui fișier: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ find workspace/C -type f | ||
- | workspace/C/leetcode/src/226.c | ||
- | workspace/C/leetcode/src/700.c | ||
- | workspace/C/leetcode/src/278.c | ||
- | [...] | ||
- | </code> | ||
- | În exemplul de mai sus i-am transmis utilitarului ''%%find%%'' că vrem să căutăm în directorul ''%%~/workspace/C%%'' toate fișierele text (regular file) ''%%-type f%%''. | ||
- | |||
- | **Exercițiu:** Accesați pagina de manual a utilitarului find (''%%man find%%'') și căutați opțiunea ''%%-type%%''. Căutați în directorul ''%%workspace/C%%'' după fiecare tip de fișier pentru care oferă suport opțiunea ''%%-type%%''. | ||
- | |||
- | <note> | ||
- | |||
- | |||
- | Reminder: pentru a căuta în man folosim ''%%/%%'' pentru a intra în search mode și apoi introducem textul pe care îl căutam ''%%-type%%'' urmat de tasta ''%%Enter%%''; pentru a ne duce la următorul rezultat al căutării folosim tasta ''%%n%%'' (next). | ||
- | </note> | ||
- | |||
- | În cadrul unei căutări putem să combinăm opțiunile de căutare: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ find workspace/C -type f -name "*search*" | ||
- | workspace/C/searching/modified_binary_search.c | ||
- | workspace/C/searching/ternary_search.c | ||
- | workspace/C/searching/jump_search.c | ||
- | workspace/C/searching/binary_search.c | ||
- | </code> | ||
- | În exemplul de mai sus căutăm toate fișierele text care conțin șirul **search** în nume. | ||
- | |||
- | Utilitarul ''%%find%%'' ne permite să executăm comenzi asupra rezultatelor căutării. Facem acest cu opțiunea ''%%-exec command {} ;%%''. Atunci când folosim ''%%-exec%%'', rezultatul căutării va înlocui șirul **'{}'** în textul comenzii; comanda de executat trebuie să se termine în caracterul ''%%;%%''. | ||
- | |||
- | Observăm exemplul de mai jos: | ||
- | |||
- | <code bash> | ||
- | student@uso:~$ find workspace/C -type f -name "*search*" -exec ls -l {} \; | ||
- | -rw-r--r-- 1 student student 3312 sep 17 19:20 workspace/C/searching/modified_binary_search.c | ||
- | -rw-r--r-- 1 student student 1782 sep 17 19:20 workspace/C/searching/ternary_search.c | ||
- | -rw-r--r-- 1 student student 1624 sep 17 19:20 workspace/C/searching/jump_search.c | ||
- | -rw-r--r-- 1 student student 2799 sep 17 19:20 workspace/C/searching/binary_search.c | ||
- | -rw-r--r-- 1 student student 867 sep 17 19:20 workspace/C/searching/other_binary_search.c | ||
- | </code> | ||
- | În exemplul de mai sus, argumetul opțiunii ''%%exec%%'' este ''%%ls -l {} \;%%''. În cuvinte, pentru fiecare fișier text care conține șirul **search** vom afișa informații în format lung (''%%ls -l {}%%''). Observăm că ''%%-exec%%'' se încheie cu ''%%\;%%'': este nevoie să escapăm caracterul ''%%;%%'' pentru ca acesta să fie interpretat de către utilitarul ''%%find%%'' și nu de către terminalul în care rulăm, exact ca în cazul ''%%-name PATTERN%%''. | ||
- | |||
- | În secțiunile ce urmează vom vedea cum ne folosim de opțiunea ''%%exec%%'' pentru a face recursiv search & replace în fișiere. | ||
=== Exerciții === | === Exerciții === | ||
- | - Folosind ''%%find%%'' căutați fișierele care conțin șirul ''%%bubble_sort%%'' în nume. | + | - Folosind ''%%find%%'' căutați fișierele care conțin șirul ''%%tmp%%'' în nume. Hint: [starting point] este ''%%/%%''. |
- | - Folosind ''%%find%%'' căutați fișierele care conțin șirul ''%%quick_sort%%'' în nume. | + | - Folosind ''%%find%%'' căutați fișierele care conțin șirul ''%%bin%%'' în nume. Hint: [starting point] este ''%%/%%''. |
- | - Folosind ''%%find%%'' căutați fișierele care conțin șirul ''%%merge_sort%%'' în nume. | + | |
- | - Folosind ''%%find%%'' căutați fișierele care conțin șirul ''%%sort%%'' în nume. | + | |
**Note de subsol** | **Note de subsol** | ||