L'altro giorno ho scritto:
La console, come vedete, non serve. Tuttavia è vero che molte delle operazioni che vi ho fatto vedere su Ubuntu si possono fare anche da console. Questa è una feature in più e non una cosa negativa
Oggi vi mostrerò un esempio lampante di questo assunto. Ieri avevo la necessità di stampare numerosi documenti pdf che mi erano stati consegnati su una chiavetta usb. Molti di questi documenti, pur essendo in formato pdf, erano stati rinominati come file html. Sono misteri dell'informatica, a volte l'utente che non sa quello che fa finisce per compiere azioni piuttosto strane. Per verificare il reale tipo di file di tutti i file che mi erano stati consegnati ho digitato, nella cartella contenente i documenti, il seguente comando:
for i in `ls`; do file $i ;done
Attenzione! l'apostrofo del comando ls non è un apostrofo normale. Per ottenerrlo bisogna digitare AltGr+apostrofo
con un solo comando ho verificato il tipo di file di tutti i file presenti nella cartella in cui ho digitato il comando, ho scoperto così che, ad esempio:
08_07_2004.html: PDF document, version 1.2
è in realtà un file pdf. Come fare per rinominare tutti i file pdf che in realtà sono stati nominati erroneamente come file html? Potremmo aprire il nostro file manager e rinominare, ad uno ad uno, tutti i file presenti nella cartella, oppure, molto più comodamente, possiamo digitare da console:
for i in `ls`; do mv $i `echo $i | sed s/html/pdf/g`;done
Nota ti Bianco nei commenti, questo comando rinomina tutti i file presenti nella directory, per rinominare solo i file con estensione html è necessario digitare questo comando:
for i in `ls *.html`; do mv $i `echo $i | sed s/html/pdf/g`;done (rinomina tutte le occorrenze di html, per cui se un file dovesse chiamarsi pippohtml.html il nuovo file diventerebbe pippopdf.pdf)
for i in `ls *.html`; do mv ${i} `basename ${i} '.html'`.pdf; done (soluzione proposta da Bianco nei commenti, aggiunge semplicemente l'estensione alla fine del file, per cui un file pippohtml.html diventerebbe pippohtml.pdf)
io avevo dato per scontato che tutti i file html presenti nella directory dovessero essere rinominati. Come dice Bianco nei commenti "da un grande potere derivano grandi responsabilità", per cui quando effettuate queste operazioni fatevi sempre un backup o assicuratevi di lavorare solo sui file che dovete modificare.
per questo esempio abbiamo utilizzato sed, un potente programma in grado di effettuare semplici modifiche ad uno o più file testuali. Immaginate di dover rinominare 100-200 file con il file manager, quanto tempo impieghereste? Grazie alla console un'operazione lunga e tediosa diventa questione di un attimo.
Manca infine la stampa dei file pdf opportunamente rinominati, sempre da console basta digitare:
for i in `ls *.pdf`; do lp $i;done
per stampare tutti i file con estensione pdf presenti nella cartella in cui abbiamo dato il comando di stampa.
Attenzione: se non avete impostato una stampante predefinita o avete più stampanti il comando non funzionerà. Allora fate così, digitate "lpstat -p -d", conoscerete così l'elenco delle stampanti installate, copiate il nome della stampante e poi, invece di dare il comando descritto precedentemente digitate: "for in in `ls *.pdf`; do lp -d nomestampante $i;done, dove nomestampante è il nome della stampante da cui volete stampare.
Leggi anche:
Leggi anche:
Se questo articolo ti è piaciuto aiutami a diffonderlo.
Segnalalo sul tuo blog, invialo agli amici, segnalalo sugli aggregatori di news.
Se vuoi seguire Doxaliber con maggiore tranquillità iscriviti ai feed, trovi i link in alto a destra.
Intanto questo blog ha già:
senza contare i lettori dei feed per categorie e gli abbonati alla newsletter!
> Come fare per rinominare tutti i file pdf che in realtà sono stati nominati erroneamente come file html?
> Potremmo aprire il nostro file manager e rinominare, ad uno ad uno, tutti i file presenti nella cartella,
> oppure, molto più comodamente, possiamo digitare da console:
> for i in `ls`; do mv $i `echo $i | sed s/html/pdf/g`;done
Cosi`hai in realta` rinominato tutti i file presenti nella directory corrente, sostituendo nel nome di ogni file ogni occorrenza della stringa "html" con "pdf": "manuale_html.html" diventa "manuale_pdf.pdf"; senza contare il fatto che se ci sono file che contengono degli spazi nel nome, il comando fallisce.
> Grazie alla console un’operazione lunga e tediosa diventa questione di un attimo.
Vero, ma come dice il saggio "da un grande potere deriva una grande responsabilita`"
Bianco
Ti piace questo commento?
2
0
Hai ragione Bianco, ho dato per scontato che tutti i file della directory dovessero essere cambiati (questo è il mio caso). Per modificare solo un'estensione specifica:
for i in `ls *.html`; do mv $i `echo $i | sed s/html/pdf/g`;done
Per quanto riguarda gli spazi invece non so come risolvere, per questo motivo io non li uso mai. Suppongo esista un comando anche per questo, ma non lo ricordo. Idee?
PS Hai ragione, da un grande potere derivano grandi responsabilità..
Ti piace questo commento?
0
0
> Per modificare solo un’estensione specifica:
> for i in `ls *.html`; do mv $i `echo $i | sed s/html/pdf/g`;done
Ehm, e` sbagliato anche questo: cosi` sostitusci _tutte_ (quella 'g' alla fine di sed) le occorrenze della stringa "html" con "pdf" in tutti i file che terminano per ".html"... vale ancora l'esempio che ho fatto sopra: “manuale_html.html” diventa “manuale_pdf.pdf”.
Per fare quello che vuoi tu, dovresti fare una cosa cosi`:
for i in `ls *.html`; do mv ${i} `basename ${i} '.html'`.pdf; done
> Per quanto riguarda gli spazi invece non so come risolvere, per questo motivo io non li uso mai. Suppongo esista un comando anche per questo, ma non lo ricordo. Idee?
Si risolve facilmente modificando la variabile d'ambiente IFS (Internal Field Separator); qualche riferimento:
http://tldp.org/LDP/abs/html/internalvariables.html#IFSH
http://fvue.nl/wiki/Bash:_Show_IFS_value
Bianco
Ti piace questo commento?
0
0
Vabbé, ma è davvero remota la possibilità che un file contenga al suo interno il nome di estensione del file stesso, veramente raro (ed in ogni caso il danno non sarebbe così grande). Il tuo comando comunque non funziona, sto cercando di capire perché. Grazie per gli altri link intanto. Correggo, funziona.
Ti piace questo commento?
0
0
> Vabbé, ma è davvero remota la possibilità che un file contenga al suo interno il nome di estensione del file stesso, veramente raro (ed in ogni caso il danno non sarebbe così grande).
Se vuoi fare uno script utile, non puoi fare questo tipo di assunzione, non ti pare? Per quanto riguarda il danno, dipende... io lo considero un danno grave.
> Il tuo comando comunque non funziona, sto cercando di capire perché.
L'ho provato sia in bash che in sh (su Ubuntu 9.10) e funziona correttamente; se l'hai copioincollato da qui, ho notato che gli apici singoli vengono "tradotti" in modo errato: sostituiscili usando l'apice corretto; i backtick sono invece riportati correttamente.
Ti piace questo commento?
0
0
"L’ho provato sia in bash che in sh (su Ubuntu 9.10) e funziona correttamente"
Avevo già corretto il precedente commento, affermando che funziona.
In quanto al resto, il tuo comando trasforma un file
pippohtml.html
in
pippo.html.html.pdf
il mio
pippohtml.html
in
pippopdf.pdf
formalmente la tua soluzione è più corretta, per certi versi il comando in sé è anche più elegante, ma fatico a considerare un errore grave il "possibile" cambiamento di un nomefile quando alla fine, nello specifico, ciò che stiamo facendo è proprio rinominare un file. Ammetto che comunque la tua soluzione è migliore e la metto nell'articolo.
Ti piace questo commento?
0
0
> Avevo già corretto il precedente commento, affermando che funziona.
Scusa, stavo scrivendo la risposta e non ho visto il commento aggiornato
> In quanto al resto, il tuo comando trasforma un file
> pippohtml.html
> in
> pippo.html.html.pdf
Eh, no
Quel "basename ${i} '.html'" serve proprio per avere il nome del file senza estensione.
Il mio comando fa questo:
bianco@azrael:~/temp$ touch pippohtml.html
bianco@azrael:~/temp$ ls
pippohtml.html
bianco@azrael:~/temp$ for i in `ls *.html`; do mv ${i} `basename ${i} '.html'`.pdf; done
bianco@azrael:~/temp$ ls
pippohtml.pdf
che e` esattemente quello che volevamo, ossia cambiare l'estensione, non aggiungerne una
Considero "grave" il cambiamento nel nome del file perche` non e` quello che si vuole ottenere in questo caso. Mi spiego meglio: se faccio uno script che deve cambiare l'estensione di un certo tipo di file, mi aspetto che la modifica dell'estensione sia la _sola_ modifica applicata ai file; cambiare anche parte del nome e`, in questo caso, un effetto collaterale. Se invece faccio uno script il cui scopo e` sostituire la stringa "xxx" con la stringa "yyy" ovunque nel nome del file (estensione compresa), allora quello che hai scritto tu e` corretto.
Ti piace questo commento?
0
0
hey, puoi usare anche $() al posto dei backtick...
Ti piace questo commento?
0
0
Ok, hai ragione, l'errore è causato dagli apici che non sono corretti, modificando gli apici il file viene rinominato correttamente. Bene, oggi ho imparato qualcosa in più, grazie.
Ti piace questo commento?
0
0
> Ok, hai ragione, l’errore è causato dagli apici che non sono corretti, modificando gli apici il file viene rinominato correttamente.
Oggi e` il tuo giorno fortunato
: io di wordpress non so assolutamente nulla, ma ho un collega che lo usa molto e gli ho chiesto consulto:
questo plugin risolve il problema degli apici:
http://wordpress.org/extend/plugins/no-curly-quotes/
> Bene, oggi ho imparato qualcosa in più, grazie.
Sono contento di essere stato utile
Ti piace questo commento?
0
0
Installato pure questo...
Ciao!
Ti piace questo commento?
0
0
Ciao, ci sono ovviamente mille modi alternativi di eseguire questa operazione. Mi permetto di correggere la riga di sed in modo da ottenere il risultato voluto:
sed 's/html/pdf/g'
come e' gia' stato evidenziato non produce il risultato corretto, poichè cambia qualsiasi occorrenza della stringa "html" in "pdf" (quindi abc_html_def.html diventerebbe abc_pdf_def.pdf). Se pero' si modifica cosi':
sed 's/\.html$/\.pdf/g'
allora viene modificata solo l'ultima occorrenza di "html" all'interno della stringa, purche'
preceduta da un "."
Per la questione degli spazi, puoi anteporre e postporre dei doppi apici:
for i in *.html; do mv "$i" "`echo $i | sed 's/\.html$/\.pdf/g'`";done
Ti piace questo commento?
0
0
Eh si, bash è davvero potente!
Non avevo davvero pensato alla soluzione dei doppi apici, eppure la uso sempre!
Ti piace questo commento?
0
0
ciao secondo me il metodo migliore per farlo è usando la manipolazione delle variabili dela bash
for i in *.html; do mv $i ${i%.html}.pdf; done;
per i dettagli: http://tldp.org/LDP/abs/html/string-manipulation.html
ciao ciao
Ti piace questo commento?
1
0
scusa, il primo comando non puoi sostituirlo con
file *
?
Ti piace questo commento?
0
0
Si, ma volevo utilizzare sempre lo stesso metodo "for" per uniformità e chiarezza. D'altronde, come abbiamo visto anche dagli altri commenti, esistono mille modi diversi per giungere alla stessa soluzione.
Ti piace questo commento?
0
0
Perché rischiare di rinominare anche file .html "autentici"?
Questo comando considera tutti i file (indipendentemente dall'estensione iniziale) ma rinomina solamente quelli che sono "davvero" dei PDF. Purtroppo la nuova estensione viene aggiunta e non sostituisce la vecchia: il risultato finale è senz'altro meno elegante ma, secondo me, più efficace.
for i in *; do file $i | grep "PDF document" && mv $i $i.pdf; done
Ti piace questo commento?
0
0
Bella soluzione.
Ti piace questo commento?
0
0