Newsgroup: it.comp.os.linux.iniziare
Titolo: un aiuto sul comando cp (è l'ultima!!!)... spero :)

Ciao, come sapete sono cieco e avrei bisogno di sapere se c'è la
possibilità di copiare un cd sull'hd ma senza inludere i file non
copiabili come ad es. quelli che contengono "�".
Vi prometto che se rispondete a questa staro zitto per un po' :-)

On Dec 8, 1:40 pm, "Guido Nasi (è il mio nome non la mia

cioe' vuoi copiare tutto tranne i file che contengono caratteri strani
(tipo spazi, a capo, tabulazioni ecc.?)
i carateri di cui parli potrebbero essere i caratteri di controllo (i
primi 31 del codice ascii) + lo spazio
quindi potresti prima copiare tutto il CD da qualche parte con "cp -a"
quindi cercare tutti i file con uno di quei caratteri nel nome, e
cancellarli
(supponendo di trovarsi nella directori radice del CD copiato...)
$ find . -print0 | grep -z "[[:cntrl:] ]" | while read -d ""; do rm
"$REPLY"; done
quindi ricrei una nuova imagine ISO con i file "scomodi" eliminati...
ma forse era meglio rinominarli sostituendo i caratteri di controllo e
gli spazi con dei punti di domanda, no?

 "$REPLY"; done
per essere precisi, il comando "read" andrebbe usato anche con
l'opzione -r
altrimenti il carattere backslash non viene letto correttamente

 gli spazi con dei punti di domanda, no?
se volevi rinominarli, invece di cancellarli, potresti prendere come
spunto una riga tipo questa...
$ find . -print0 | grep -z "[[:cntrl:] ]" | while read -rd ""; do mv
"$REPLY" "${REPLY//[[:cntrl:] ]/?}"; done
buon divertimento.
ciao

 "$REPLY" "${REPLY//[[:cntrl:] ]/?}"; done
umpf!
c'e' un "piccolo" bug... se le directory contengono caratteri di
controllo nel nome, queste vengono rinominate, e i file al loro
interno non vengono piu' trovati
in quel caso mv esce con un errore, e tocca ridare il comando...
risolvere il bug pero' mi sa che e' impossibile. (?)

antoniomac5 wrote:

"Man find", questo sconosciuto.

> "Man find", questo sconosciuto.
uff!! che faticaccia che dev'essere stata per te... grazie grazie,
davvero, grazie infinite...

antoniomac5 wrote:

Per me no, ma sicuramente per te e' stata (o e' ancora) una faticaccia.

> Per me no, ma sicuramente per te e' stata (o e' ancora) una faticaccia.
ah... fatica inutile!!!
find non puo' rinominare un file... non si puo' sostituire i caratteri
di controllo con dei punti di domanda solo con find.
secondo me, con la tua frasetta sibillina hai solo bluffato.
comunque riconosco che il pipe a grep si poteva evitare usando la
ricerca di espressioni regolari di find
e in effetti non ho ancora mai letto con attenzione tutta la man di
find.
ma ad intuito dico lostesso che hai bluffato

antoniomac5 wrote:

Non ho bluffato, ho solo risposto alla domanda che ti ponevi dicendo che era 
"impossibile".

 "impossibile".
e continuo ad affermarlo!
non e' possibile, con una sola riga di bash, sostituire tutti i
caratteri di controllo e gli spazi di tutti i nomi di file con dei
punti di domanda.
dammi le tue coordinate bancarie, e la riga (una!!!) di bash che lo fa
e ti accredito 10 euro!

 e ti accredito 10 euro!
Mia ultima risposta.
Tu avevi detto:
"c'e' un "piccolo" bug... se le directory contengono caratteri di
controllo nel nome, queste vengono rinominate, e i file al loro
interno non vengono piu' trovati
in quel caso mv esce con un errore, e tocca ridare il comando...
risolvere il bug pero' mi sa che e' impossibile. (?)"
E io ho detto che in "man find" (che ancora non hai letto) c'e' un modo per 
evitare il problema (sempre assumendo che uno si ostini ad usare find).

 e ti accredito 10 euro!
non voglio metterti limiti di tempo... pero' considera anche
l'inflazione...

 evitare il problema (sempre assumendo che uno si ostini ad usare find).
hei! un'altra... WOW!
grazie ancora... meraviglie su meraviglie... si puo' fare senza find?
io dico che una cosa e' impossibile, e tu non solo dici che e'
facilissima, ma che ci sono pure piu' modi per farla...
e sono talmente facili e stupidi, che non meritano neanche di essere
scritti
ora o io sono un completo idiota senza speranza o tu sei un fanfarone
ma per tua fortuna io so di essere un copleto idiota senza
speranza... :)

$ mkdir a$'\n'capo
$ touch a$'\n'capo/spa\ zio
$ find . -regextype posix-egrep -regex ".*[[:cntrl:] ].*" -exec rename
's/[[:cntrl:] ]/?/g' {} \;
find: `./a\ncapo': No such file or directory
----
comunque, se qualcuno passasse mai di qui, c'e' un altro "problemino"
di cui si dovrebbe tener conto
se due file differiscono nel nome solo per dei caratteri di controllo
o per degli spazi, finirebbero sovrascritti
bisognerebbe usare una opzione tipo --force-backup di cp (che pero'
non esiste ne su mv, ne su rename)
insomma... i miei 10 euro sono al sicuro pare!

 find: `./a\ncapo': No such file or directory
$ mkdir a$'\n'capo
$ touch a$'\n'capo/{a$'\n'capo,spa\ zio,ta$'\t'b}
$ find . -depth -regextype posix-egrep -regex ".*[[:cntrl:] ].*" -
execdir rename 's/[[:cntrl:] ]/?/g' {} \;
$ ls -lb a\?capo
total 0
-rw-r--r-- 1 antoniomac5 antoniomac5 0 2009-12-09 00:15 a\ncapo
<---------
-rw-r--r-- 1 antoniomac5 antoniomac5 0 2009-12-09 00:15 spa?zio
-rw-r--r-- 1 antoniomac5 antoniomac5 0 2009-12-09 00:15 ta?b
non c'e' storia... il segreto lo sa solo antani... e se lo terra' ben
stretto!!!

 primi 31 del codice ascii) + lo spazio
I caratteri di controllo sono i primi trentadue più il rubout 
e senza lo spazio,
$ cat > pippo.c                                                                                                                 
#include <stdio.h>                                                                                                                         
int main() {
 
unsigned char i;
  for(i=0;i<255;i++)
    if (iscntrl(i)) 
      printf("%03d\n",i);
  if (iscntrl(i))
    printf("%03d\n",i);
  return 0;
}
$ gcc -o pippo pippo.c
$ ./pippo
000
001
...
030
031
127

 #include <stdio.h>                                                                                                                         
ma ti pare che c'era bisogno di scomodare il C per sta robetta?
$ for i in {0..3}{0..7}{0..7}; do echo -e \\0$i | grep -q "[[:cntrl:]]" 
&& echo "ibase=8; $i" | bc; done
0
1
2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
127

 ma ti pare che c'era bisogno di scomodare il C per sta robetta?
Primo comandamento del programmatore:  Non inventare l'acqua calda.
Avevo questo programmillo in C, lo avevo sottomano, lo ho postato.

> Primo comandamento del programmatore:  Non inventare l'acqua calda.
Vuoi mettere inventare l'acqua calda, e aprire semplicemente un rubinetto?
comunque nell'esempio di prima mancava il carattere 10 (invio)
$ for i in {0..3}{0..7}{0..7}; do echo -en \\0$i \\0 | grep -zq 
"[[:cntrl:]]" && echo "ibase=8; $i" | bc; done
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
127
aaaahh.... bollente!!!

 
Non direi proprio "aprire semplicemente un rubinetto". Va bene, non ti 
piace il C, usa Perl o AWK, questi sono i linguaggi che ti semplificano 
la vita, non certamente la bash che ti costringe a reinventare l'acqua 
calda. Considera ad esemplio l'implementazione in AWK del mio 
programma C:
awk ' BEGIN { 
  for (i=0;i<=255;i++) { 
    c=sprintf("%c",i)
    if ( c ~ /[[:cntrl:]]/ ) print c,i 
  }
}'
sono quasi identiche, cambiano solo due cose:
1) In AWK mi sono avvalso delle espressioni regolari
2) la conversione di tipo è implicita in C ed esplicita in AWK (effettuata 
    mediante la funzione sprintf)
Considera quest'ultimo punto; C non ti costringe ad inventare 
l'acqua calda per effettuare conversioni tra tipi.
Invece la tua soluzione BASH:
 
for i in {0..3}{0..7}{0..7}
  do 
    echo -en \\0$i \\0 | 
    grep -zq "[[:cntrl:]]" && 
    echo "ibase=8; $i" | 
    bc;
  done
La prima volta hai inventato l'acqua calda quando hai fatto tutti 
quegli arzigogoli poco portabili* con il for e l'espansione deli 
parametri perché non potevi fare una conversione di tipo.
La seconda volta hai inventato l'acqua calda quando sei stato 
costretto ad usare bc per poter effettuare la conversione inversa.

 "[[:cntrl:]]" && echo "ibase=8; $i" | bc; done
La cosa fondamentale però sfugge ancora. 
Se vuoi vedere cosa è un carattere di controllo per il C devi per forza 
usare il C e devi per forza usare la funzione iscntrl() del C.
E ti sfugge ancora un baco colossale di grep: per grep l'input è 
formato da righe di testo terminate da un a capo \0x0a o per il grep 
GNU anche da da un carattere nullo \0x00 se si desidera.
Il baco è che non puoi usare grep per discriminare i caratteri di 
controllo perché grep non può trattare stringhe contenti il 
terminatore, quindi o mancherò il ritorno a capo od il carattere nullo.
È inutile smanettare con le varie opzioni di grep, il meglio che puoi 
fare è fare un controllo incrociato... 
Perché ad un certo punto mi è venuta in mente l'espressione 
inglese /brain/ /damaged/ ?

 inglese /brain/ /damaged/ ?
troppo LSD in gioventu'?
a parte gli scherzi
mi piace Bash.... le pipe e i descrittori di file... comandi come
eval, xargs, e una miriade di piccoli comandini con le opzioni piu'
strane per fare le cose piu' impensate...
ci son veramente tante cose da sapere.. e non si puo' sapere tutto
cosi' ognuno deve fare le sue scelte... e credo che la prima da fare
sia se restare sulla shell, o se andarsene col C
il C e' difficile... le librerie sono tante, e le funzioni di
libreria, se si vuol scrivere bene, bisogna conoscerle
bash e' un po' piu' facile... imparare com'e' fatto il sistema e
pilotarlo con bash non e' un traguardo impossibile
in una cinquina d'anni potrei anche raggiungerlo
quando saro' vecchio, e in pensione... forse mi decidero' ad inventare
l'acqua calda in C
per il momento la invento in bash, che va benone lostesso.
grazie comunque per i buoni consigli
ciao

> quegli arzigogoli poco portabili* con il for e l'espansione deli
esiste una sola shell.
bash
non lo dico io, lo dice Tom Cristiansen
leggi, se hai voglia...
http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/
in sostanza dice:
The csh is a tool utterly inadequate for programming,  and its use for
such purposes should be strictly banned!
riporta un sacco di esempi in cui csh non funziona...
lui consiglia di usare "sh", ma e' ovvio che il documento e' datato
(1996)
oggi Bash e' la shell standard
chi usa un'altra va solo incontro a problemi, senza nessun vantaggio

antoniomac5 wrote:

Certo che se tu avessi 10 centesimi per ogni cazzata che spari, saresti 
ricco...
Non esistono solo bash e csh (che non esiste piu', oggi c'e' tcsh).
(tra parentesi, e' vero che csh per lo scripting e' tremenda, ma come shell 
interattiva ha molte cose ottime)
Mai sentito parlare di ksh e zsh, ad esempio?
La stessa bash ha copiato a mani basse molte delle sue feature da shell 
precedenti, soprattutto ksh (che comunque e' ancora superiore, per non 
parlare di zsh che e' proprio un altro pianeta).
Mi aspetto una risposta nello stile della tua arguta ironia.

 strane per fare le cose piu' impensate...
Purtroppo la bash non è tutto il mondo, esistono altre shell, con 
la bash non si può fare tutto e non è lo strumento più adatto per 
fare molti lavori. AWK fu inventato per superare le limitazioni della
shell e Perl fu inventato per superare le limitazioni di AWK. 
Voglio dire che la cosa importante è ottenere risultati; fare molti
sforzi per imparare un linguaggio come la bash è lodevole ma
è meglio concentrarsi sull'ottenere il risultato con lo strumento 
migliore. Molte volte questo strumento è la  bash ma molto 
più spesso non lo è.

 chi usa un'altra va solo incontro a problemi, senza nessun vantaggio
Mi spiace devo deluderti per entrambe le affermazioni. La bash non è 
affatto lo standard e prova altre shell prima di fare confronti.

 Mi aspetto una risposta nello stile della tua arguta ironia.
$ ksh -c "echo {0..1}{0..1}{0..1}"
000 001 010 011 100 101 110 111
ok, ksh e' buona.
$ zsh -c "echo {0..1}{0..1}{0..1}"
000 001 010 011 100 101 110 111
ok, zsh e' pure buona.
$ tcsh -c "echo {0..1}{0..1}{0..1}"
0..10..10..1
tcsh fa schifo!!
:)
saludos

 echo "ibase=8; $i"; fi | bc; done; done | sort -n | uniq
se mai esistesse un pazzo che si legge "cluster" simili... si poteva
un po' abbreviare cosi'...
$ for repeat in one two; do for i in {0..3}{0..7}{0..7}; do if test
$repeat == one; then echo -en "\0$i\0" | grep -zq "[[:cntrl:]]"; else
echo -e "\0$i" | grep -q "[[:cntrl:]]"; fi && echo "ibase=8; $i" | bc;
done; done | sort -nu


 più spesso non lo è.
daccordo
infatti quello a cui punto io non e' scrivere software, ma solo
imparare come funziona il sistema operativo
al massimo mi possono interessare gli script d'avvio (che adesso mi
pare li stiano riscrivendo in ash)
so che alcune parti sono scritta anche in perl... ho studiato un po'
awk e devo dire che e' molto molto bello, pero' una cosa per volta
grazie per i consiglic
ciao

 affatto lo standard e prova altre shell prima di fare confronti.
se una shell non e' compatibile con bash, e mi metto ad usarla,
scomettiamo che presto o tardi (piu' presto che tardi) mi ritrovo con
dei problemi a causa di "bashismi" di qualche script in giro per il
sistema?

azz... c'hai ragione... buona un cazzo
$ zsh -c "for i in {0..1}{0..1}; do echo -$i-; done;"
--
--
--
--
$ ksh -c "for i in {0..1}{0..1}; do echo -$i-; done;"
--
--
--
--
che cosa stupida... se non ci fosse gia' bash, manderei una mail di
protesta agli sviluppatori!!