1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
21:03 <@valhalla> Ciao a tutti, benvenuto alla quinta lezione del corso sulla riga di comando
21:03 <@valhalla> come al solito, spostarsi sulla directory delle altre volte con cd, pwd ed ls per controllare, e poi si pu`o scaricare il materiale di stasera
21:03 <@valhalla> wget http://www.lifolab.org/corsi/2014-linea_di_comando/riga_di_comando-lezione_5.tar.xz
21:03 -!- polva [~polva@host33-135-dynamic.43-79-r.retail.telecomitalia.it] has joined #lifo
21:03 <@valhalla> e poi scompattarlo con tar -x -v -f riga_di_comando-lezione_5.tar.xz
21:05 -!- JulesX [~lorenzo@adsl-ull-235-115.51-151.net24.it] has joined #lifo
21:05 <@valhalla> come al solito, se ci sono domande si possono fare sul canale #lifo-comande
21:05 <@valhalla> ehm
21:05 <@valhalla> #lifo-domande
21:05 -!- valhalla changed the topic of #lifo to: LIFO - Laboratorio Informatico Free ed Open - 18 febbraio: quinta lezione riga di comando http://lifolab.org/corsi/2014-linea_di_comando.html - http://lifolab.org - http://social.gl-como.it/profile/lifo - domande su #lifo-domande
21:06 <@valhalla> dove c'è diego71 che le riporta qui in canale (o se avete qualche problema vi aiuta direttamente a risolverlo)
21:07 <@valhalla> l'argomento di stasera è "cercare le cose"
21:09 <@valhalla> negli ultimi anni si sono diffuse un sacco di soluzioni (specialmente da interfaccia grafica) per indicizzare i file e poi ritrovarli, ma stasera parliamo dei due tool base forniti dall'interfaccia testuale per cercare file (find) e per cercare nei contenuti dei file
21:09 <@valhalla> innanzitutto, prepariamo l'ambiente: ``cd lezione_5`` ``mkdir esercizi`` ``cd esercizi``
21:09 <@valhalla> a questo punto, possiamo ricordare che già nella prima lezione avevamo parlato di caratteri speciali per indicare pi`u file con una stringa sola
21:10 <@valhalla> ad esempio, ``ls ../../lezione_?`` vi elenca i contenuti di tutte le directory col nome che inizia per ../../lezione_ seguito da un solo carattere
21:11 <@valhalla> questo è parte del cosiddetto "globbing", ovvero una sintassi abbastanza semplice per specificare più stringhe in base ad un pattern che queste rispettano
21:12 <@valhalla> l'altro carattere molto usato che avevamo visto è ``*``, che indica zero o pi`u caratteri qualsiasi
21:12 <@valhalla> (qui c'è un errore nelle dispense, dove ho scritto uno o più, invece vale anche zero caratteri)
21:13 <@valhalla> ad esempio, prepariamoci un po' di file con ``touch file_uno file_due file_tre file_quattro cinque``, che crea un po' di file vuoti
21:13 <@valhalla> ``ls`` per vedere cosa c'è, e poi ``ls file_*`` che vedremo stamperà solo ``file_uno file_due file_tre file_quattro``, ma non ``cinque``
21:14 <@valhalla> possiamo anche vedere tutti i file con un numero da tre caratteri, con ``ls file_???``
21:14 <@valhalla> (quindi né file_quattro, né cinque)
21:16 <@valhalla> questo globbing viene effettuato direttamente dalla shell, che poi passa ai programmi l'elenco dei file che soddisfacevano i requisiti
21:16 <@valhalla> ci sono domande fin qui?
21:17 <@valhalla> ovviamente, elencare file in questo modo non è molto utile ai fini del trovare qualcosa che non sappiamo dove sia :)
21:17 <@valhalla> a questo viene in aiuto il comando find
21:19 <@valhalla> find è un comando che ha una sintassi leggermente diversa dal solito, e a volte fa uso di magia nera, ma serve per trovare sul filesystem dei file che soddisfano determinate condizioni nei *metadata*
21:20 <@valhalla> ovvero, può fare ricerche sul nome, sul tipo di file, sulla data, proprietario, dimensioni e quant'altro, ma non sui contenuti
21:20 -!- albertux [~Icedove@dynamic-adsl-78-14-228-201.clienti.tiscali.it] has quit [Quit: Alla prossima...]
21:20 <@valhalla> la sintassi è ``find $DOVE_CERCARE $COSA_CERCARE``
21:21 <@valhalla> dove $COSA_CERCARE è composto da varie opzioni -nome_opzione valore
21:21 <@valhalla> ad esempio, diamo il comando ``touch file_une``
21:22 <@valhalla> e poi ``find ../../ -name "file_un?"
21:22 <@valhalla> notare le ": servono perché vogliamo che sia find a leggere quel ?, non vogliamo che venga interpretato dalla bash
21:23 <@valhalla> se non avessimo messo le virgolette, ``find ../../ -name file_un?`` sarebbe stato trasformato in ``find ../../ -name file_une file_uno``, che non è quello che vogliamo (e da errore)
21:23 <@valhalla> quel comando trova nella directory ../../ tutti i file il cui nome è ``file_un`` seguito da un carattere qualsiasi, e niente altro
21:24 <@valhalla> se usiamo ad esempio ``find ../../ -name "file_u?"`` non troverà niente, mentre nel nostro caso specifico ``find ../../ -name "file_u??" troverà gli stessi file
21:24 <@valhalla> domande fin qui?
21:24 <@valhalla> direi di no, proseguo
21:25 <@valhalla> un altra condizione che ogni tanto si usa sono le dimensioni, ad esempio ``find ../../ -size 1504c`` trova tutti i file che occupano esattamente 1504 byte
21:26 <@valhalla> il suffisso ``c`` sta per byte, ci sono anche k, M e G che stanno più intuitivamente per kilobyte, megabyte e gigabyte
21:27 <@valhalla> (può essere utile ad esempio per trovare file da esattamente 2G, che probabilmente son stati troncati su qualche filesystem primitivo :)
21:28 <@valhalla> per il nome, dimenticavo, c'è anche la variante -iname, che cerca il nome ignorando maiuscole e minuscole
21:28 <@valhalla> e poi ci sono millemila altre opzioni, che si trovano sulla pagina di manuale
21:29 <@valhalla> domande fin qui?
21:29 <@diego71> < tiziano> perché find ../../ e non find . (directory corrente)?
21:29 <@valhalla> perché così trovava anche riga_di_comando-lezione_5.tar.xz che è quello di cui avevo controllato le dimensioni :)
21:29 -!- Delfino1983 [~Alex@host40-54-dynamic.250-95-r.retail.telecomitalia.it] has joined #lifo
21:29 -!- Delfino1983 [~Alex@host40-54-dynamic.250-95-r.retail.telecomitalia.it] has quit [Changing host]
21:29 -!- Delfino1983 [~Alex@unaffiliated/delfino1983] has joined #lifo
21:30 <@valhalla> effettivamente più spesso lo si fa o sulla directory corrente oppure su qualche directory "famosa"
21:30 -!- Delfino1983 [~Alex@unaffiliated/delfino1983] has quit [Client Quit]
21:30 <@valhalla> tipo ``find /home -size +128M`` per trovare che utenti di un sistema stanno sprecando spazio :D
21:31 <@valhalla> altre domande?
21:31 <@valhalla> (ovvero, trovare i file nelle directory sotto ``/home`` che occupano più di 128 MB
21:32 <@diego71> riassumo la domanda di gioque: differenze tra find e locate
21:33 <@valhalla> locate tiene un indice di tutti i nomi di file che c'erano sul filesystem quando ha fatto ha fatto la passata di indicizzazione
21:34 <@valhalla> di solito i sistemi sono configurati (tramite cron, che per`o qui è un po' OT) per fare quella passata ogni giorno o ogni settimana, ma se si è aggiunto qualcosa di più recente non lo trova
21:35 <@valhalla> find invece legge i contenuti del disco nel momento in cui lo si lancia, e quindi è in generale pi`u lento, ma permette anche di trovare file recenti e di usare criteri diversi dal nome del file
21:35 <@valhalla> altre domande?
21:36 <@valhalla> < polva> non c'è quindi un modo per trovare file con un range di dimensione?
21:36 <@valhalla> usando due volte -size, una volta con +$DIMENSIONE_MINIMA ed una volta con -$DIMENSIONE_MASSIMA
21:36 -!- malo_ [~malo@217.203.145.211] has quit [Quit: Sto andando via]
21:37 <@valhalla> altre domande?
21:37 <@diego71> < tiziano> posso usera find per cercare solo directories rispondenti a determinati criteri?
21:38 <@valhalla> uno dei criteri può essere -type d per dire che quello che vuoi trovare deve essere una directory
21:38 <@valhalla> (oppure -type f per un file regolare, o -type l per un link simbolico)
21:38 <@valhalla> poi dipende da cosa vuoi come "determinati criteri"
21:38 <@valhalla> altre domande?
21:39 <@valhalla> un'altra cosa che find può fare è agire sui file trovati
21:39 <@valhalla> non vi faccio esempi dell'opzione -delete, con la quale è mooooolto facile fare danni
21:40 -!- rasalgethi [~quassel@host111-245-dynamic.17-79-r.retail.telecomitalia.it] has left #lifo []
21:40 <@valhalla> ma si pu`o eseguire un comando su ciascuno dei file trovati usando l'opzione ``-exec``:
21:40 <@valhalla> ``find ../../ -size 1504 -exec /bin/ls -l {} \;
21:40 <@valhalla> dove dopo exec tutto viene interpretato come il comando da eseguire fino a che non si arriva a \;
21:41 <@valhalla> e al posto di {} andrà il nome del file che è stato trovato
21:41 <@valhalla> in questo caso ho usato un comando che non fa danni, ovviamente il rischio di distruggere dati c'è anche qui, se si usa il comando sbagliato
21:41 <@valhalla> domande?
21:42 <@diego71> < aldagaau> find /home/ -size +128M -150M (da un errore find: Argomento "$" non valido per -size
21:42 <@valhalla> ``find ../../ -size -100c -size +10c``
21:42 -!- lucmon71 [~luca@net-93-71-184-195.cust.vodafonedsl.it] has joined #lifo
21:42 <@valhalla> ci vuole due volte l'opzione -size
21:44 <@valhalla> (nel comando di prima, ho dimenticato c per la dimensione in byte, come era prima non trovava nessun file)
21:44 <@valhalla> (quello giusto è ``find ../../ -size 1504c -exec /bin/ls -l {} \;``
21:45 <@diego71> < tiziano> $ find /home -type d -size +128M #cosa c'è di sbagliato in questo comando?
21:45 <@valhalla> che le directory hanno sempre come dimensione 4096 byte o qualche valore simile (dipende dal filesystem)
21:45 <@valhalla> i *contenuti* della directory hanno una dimensione ben diversa, ma non è quello su cui find lavor
21:45 <@valhalla> a
21:46 <@valhalla> altre domande?
21:46 <@valhalla> leggo che ci sono problemi con la sintassi di find: se vi state chiedendo se è magia nera, s`i, lo è :)
21:47 <@valhalla> è ancora pi`u pignolo della media dei programmi da riga di comando, ed ha una fraccata di opzioni anche esoteriche
21:47 <@valhalla> se non ci sono altre domande, proseguo
21:48 <@valhalla> con find si cerca tra i metadata dei file, per cercare invece sui contenuti dei file di testo esiste grep
21:48 <@valhalla> grep ha una sintassi che è il contrario di quella di find: ``grep $COSA_CERCARE $FILE_IN_CUI_CERCARE``
21:49 <@valhalla> e $COSA_CERCARE non è un semplice globbing, ma un espressione regolare
21:49 <@valhalla> che è potenzialmente pi`u potente e più complicata
21:49 <@valhalla> un caso semplice che si usa spesso è selezionare tutte le righe di uno o più file che contengano qualche stringa ben specifica
21:50 -!- huginmunin [~supybot@212-124-162-68.v4.ngi.it] has quit [Ping timeout: 272 seconds]
21:50 <@valhalla> ad esempio ``grep "(1)" ../dispensa.rst`` vi trova tutti i comandi introdotti di cui si parla in questa dispensa
21:51 <@valhalla> ``grep "(1)" ../../lezione_?/dispensa.rst`` fa più o meno la stessa cosa, in tutte le dispense di questo corso
21:51 <@valhalla> dove il ? viene interpretato dal globbing della shell, mentre grep cerca semplicemente la stringa "(1)"
21:52 <@valhalla> grep stampa poi tutta la riga che soddisfa la ricerca
21:52 <@valhalla> domande?
21:53 <@valhalla> con il semplice grep "(1)" per`o abbiamo visto che trova anche righe che non c'entrano
21:53 <@valhalla> possiamo migliorare la cosa usando alcuni dei caratteri delle espressioni regolari
21:54 <@valhalla> in questo caso, per cercare zero o più caratteri non basta pi`u usare * come prima
21:54 <@valhalla> ma bisogna dire quale carattere e quante volte si ripete
21:54 <@valhalla> ovvero, potremmo dire zero o più ripetizioni del carattere 'a' con ``a*``
21:55 <@valhalla> che è soddisfato dalle stringhe ``a``, ``aaaaa``, ``aaaaaaaaaaaaa``, ma non da ``bbbbbb``
21:55 <@valhalla> e poi possiamo comporlo col carattere ``.``, che vuol dire "qualsiasi carattere"
21:56 <@valhalla> altri due caratteri utili nelle espressioni regolari sono ``^`` che indica l'inizio della riga e ``$`` che indica la fine della riga
21:56 <@valhalla> risultato, se noi vogliamo cercare tutte le righe che iniziano per `` seguiti dal nome di un comando, seguito da (1), seguito da ``, possiamo usare:
21:56 <@valhalla> ``grep '^``.*(1)``$' ../../lezione_?/dispensa.rst
21:57 <@valhalla> e con questo (che eventualmente possiamo passare a less aggiungendo in fondo ``| less`` per leggerlo meglio abbiam trovato tutti i comandi di cui si è parlato nel corso
21:57 <@valhalla> domande?
21:57 <@diego71> < JulesX> numero di riga è possibile averlo ?
21:58 <@valhalla> sì, usando l'opzione -n: ``grep -n '(1)``$' ../../lezione_?/dispensa.rst``
21:58 <@valhalla> altre domande?
22:00 <@valhalla> (vedo che l'ultima riga mi son persa dei pezzi di copincolla, il comando è ``grep '^``.*(1)``$' ../../lezione_?/dispensa.rst``
22:00 <@diego71> < JulesX> spiegheresti bene la sintassi dell'ultimo comando
22:01 <@valhalla> allora, la prima ed ultima parte sono facili, comando e file su cui cercare :)
22:01 <@valhalla> in mezzo, tra gli '' c'è l'espressione regolare, protetta con '' perché altrimenti la shell farebbe macello dei contenuti, che son pieni di caratteri che per la shell sono speciali
22:01 <@valhalla> il primo carattere dell'espressione regolare è ^, che vuol dire "inizio della riga"
22:02 <@valhalla> poi viene ``, che sono due caratteri che so esserci nelle dispense prima di tutti i nomi di comando
22:02 <@valhalla> poi c'è .*, che significa "qualunque carattere, ripetuto zero o pi`u volte:
22:03 <@valhalla> poi di nuovo dei caratteri specifici che so essere letteralmente presenti nel file: (1)``
22:03 <@valhalla> e infine $, per dire "fine della riga:
22:03 <@valhalla> cosa che non ho detto, ma è utile dire: grep lavora sulle righe, dall'inizio fino al ritorno a capo
22:04 <@valhalla> non è banale fare ricerche che comprendano testo a cavallo tra le righe
22:04 <@valhalla> altre domande?
22:04 <@valhalla> (e sì, lo so, potevo fare un esempio più facile: questo lo era, poi ho cambiato il formato delle dispense e la versione facile non funzionava più, sorry O:-) )
22:04 <@diego71> < polva> non ho capito la differenza tra ripetizioni e caratteri. In questo caso tra "?" e "."
22:05 <@valhalla> il significato di *, ? ecc. è diverso tra il globbing (usato dalla shell e da find) e le espressioni regolari
22:05 <@valhalla> nelle espressioni regolari, ? e * si riferiscono al carattere che li precede immediatamente
22:06 <@valhalla> quindi per dire "qualunque carattere, qualunque numero di volte" si deve usare il carattere che vuol dire "qualunque carattere", che è "."
22:06 <@valhalla> e poi metterci il numero di volte, che è "*" (o ? per zero o una ripetizione soltanto)
22:07 <@diego71> erio> ma . e * non danno lo stesso risultato ?
22:08 <@valhalla> no, "." significa soltanto "qualunque carattere"
22:08 <@valhalla> ad esempio l'espressione regolare asd.qwe è soddisfatta da asdxqwe, ma non da asdxxxxxqwe
22:08 <@valhalla> invece asd.*qwe è soddisfatta da entrambe, dato che puoi avere qualunque numero di ripetizioni
22:09 <@valhalla> se invece si mette l'asterisco da solo, asd*qwe in realt`a l'asterisco si riferisce alla "d" che lo precede
22:09 <@valhalla> quindi va bene "asddddddddqwe", ma non pi`u "asdxqwe"
22:09 <@valhalla> altre domande?
22:09 <@diego71> < tiziano> "non è banale fare ricerche che comprendano testo a cavallo tra le righe", ma è possibile (con grep)oppure no?
22:10 <@valhalla> *solo* con grep no, si possono usare dei programmi che tolgano i cambi di riga, e poi dare il risultato in pasto a grep tramite dei |
22:10 <@valhalla> per`o di solito diventa un casino ottenere risultati leggibili, in molti casi
22:10 <@valhalla> altre domande?
22:11 <@diego71> < gioque> ma $ significa fine della riga che sto cercando? cioè se grep cerca sulla riga a cosa serve $ ??
22:11 <@valhalla> $ serve per dire che non si vuole nient'altro tra l'ultimo carattere scritto e la fine della riga
22:12 <@valhalla> se ad esempio si tolgono ^ e $ dall'espressione di prima, ``grep '``.*(1)``' ../../lezione_?/dispensa.rst`` si trova anche la riga 128 di ../../lezione_1/dispensa.rst
22:13 <@valhalla> che dice "Comandi principali di ``less(1)``"
22:13 <@valhalla> ovvero, non c'è solo "``less(1)``" su quella riga, ma anche dell'altro testo attorno
22:13 <@valhalla> (e noi non volevamo questo caso)
22:13 <@valhalla> altre domande?
22:15 <@valhalla> nel caso in cui le espressioni regolari vi sembrino ostiche, se pu`o consolare c'è un detto:
22:15 <@valhalla> 'Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.'
22:15 <@valhalla> per i casi semplici basta farci la mano e alla fin fine si capisce cosa vogliono dire
22:16 <@valhalla> ma ci si deve fare la mano facendo tante prove
22:16 <@valhalla> altre domande?
22:16 -!- aldagaau [~Alain@host212-195-dynamic.41-79-r.retail.telecomitalia.it] has quit [Quit: Sto andando via]
22:16 <@diego71> < polva> quindi si potrebbe continuare ad inserire condizioni prima della $ oppure si deve fare un altro "|grep"?
22:17 <@valhalla> polva: dipende da che condizioni si vogliono inserire, s`i, in molti casi è possibile unire tutto in un espressione regolare unica
22:17 <@valhalla> in altri casi, diventa pi`u leggibile passare il risutlato ad un altro grep tramite una pipe
22:17 <@diego71> < polva> e, ditemi se sbaglio, ^ e $ vanno usati sempre l'uno insieme all'altro? o si può fare un uso distaccato?
22:18 <@valhalla> sono totalmente indipendenti, si possono usare o l'uno o l'altro senza problemi
22:19 <@valhalla> gli argomenti della serata sono finiti, quindi se avete altre domande chiedete pure
22:24 <@valhalla> se non ci sono altre domande io chiudo e preparo i log da pubblicare
|