Perché la console è insostituibile. Un esempio lampante.

3 dic
2009

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:

  1. La follia dei DRM e della protezione dei contenuti, un altro lampante esempio
  2. Nokia: perché Linux si Diffonda sui Cellulari gli Sviluppatori Open Source Devono Adattarsi al Business.... dei Drm
  3. Un linguaggio non è multipiattaforma soltanto perché utilizza una VM
  4. Linux è difficilissimo, bisogna fare tutto da console, compilare il kernel, fare ./configure & make & install, problemi di dipendenze. Sarà vero?
  5. Sviluppare applicazioni web con Django. Il tutorial rilasciato gratuitamente sul web!

NOOK (Gli utenti ritengono che questo articolo valga +1, hanno votato 1 utenti)
Loading ... Loading ...



Articolo scritto da Doxaliber per Doxaliber, vuoi partecipare anche tu?

Creative Commons License

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à:
Lettori feedburner
senza contare i lettori dei feed per categorie e gli abbonati alla newsletter!

18 Risposte to “Perché la console è insostituibile. Un esempio lampante.”

  1. Bianco scrive:

    > 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? Thumb up 2 Thumb down 0

    • Doxaliber scrive:

      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à.. :mrgreen:

      Ti piace questo commento? Thumb up 0 Thumb down 0

      • Bianco scrive:

        > 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? Thumb up 0 Thumb down 0

        • Doxaliber scrive:

          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? Thumb up 0 Thumb down 0

          • Bianco scrive:

            > 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? Thumb up 0 Thumb down 0

        • Doxaliber scrive:

          "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? Thumb up 0 Thumb down 0

          • Bianco scrive:

            > 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? Thumb up 0 Thumb down 0

      • beatpanic scrive:

        hey, puoi usare anche $() al posto dei backtick...

        Ti piace questo commento? Thumb up 0 Thumb down 0

    • Doxaliber scrive:

      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? Thumb up 0 Thumb down 0

      • Bianco scrive:

        > 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? Thumb up 0 Thumb down 0

  2. Marco scrive:

    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? Thumb up 0 Thumb down 0

  3. Totem scrive:

    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? Thumb up 1 Thumb down 0

  4. Dass scrive:

    scusa, il primo comando non puoi sostituirlo con
    file *
    ?

    Ti piace questo commento? Thumb up 0 Thumb down 0

    • Doxaliber scrive:

      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? Thumb up 0 Thumb down 0

  5. Alessandro scrive:

    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? Thumb up 0 Thumb down 0

Rispondi

top