Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1

    due domande su uno script bash

    Salve.
    Scopiazzando qua e là, visto che capisco molto poco di bash, ho fatto questo piccolo script per sostituire strighe di caratteri in file:
    codice:
    for i in *; do mv "$i" `echo $i | tr -s 'à' 'a'`; done
    1) se eseguo questo comando e lui non trova stringhe da sostituire mi restituisce un errore "mv: `prova.txt' e `prova.txt' sono lo stesso file". E così per ogni file o directory in cui non ci sono caratteri da sostituire.
    Come ovviare a questo comportamento?

    2) vorrei che il comando sia valido non solo per i file e le cartelle presenti, ma che sia ricorsivo.
    Come fare??

    Grazie,
    Sergej
    :: Il Deposito
    Canti di protesta politica e sociale
    Archivio di testi e accordi

  2. #2
    Utente di HTML.it L'avatar di Ilmalcom
    Registrato dal
    Oct 2002
    Messaggi
    1,345
    1. Redirigi lo standard error su /dev/null appendendo al comando la seguente espressione:
    codice:
     2>/dev/null
    Esempio
    codice:
    mv prova.txt nuovo.txt 2>/dev/null
    2. Per farlo ricorsivo ci sono vari modi, forse la soluzione più semplice per le tue esigenze è prima lanciare il comando che hai scritto e poi, se non vi sono molti livelli di annidamento, ricorrere a forme del tipo
    codice:
    for i in */*; do mv "$i" `echo $i | tr -s 'à' 'a'`; done
    Comunque c'è ben più di una soluzione, per esempio potresti sfruttare ls -R
    codice:
    for i in `ls -R`; do mv "$i" `echo $i | tr -s 'à' 'a'`; done
    Potrebbero però verificarsi dei problemini con nomi di files particolari, vedi tu per cosa optare.

  3. #3
    Utente di HTML.it L'avatar di cacao74
    Registrato dal
    Jan 2005
    Messaggi
    2,570
    Considera anche l'opzione '--force' del comando 'mv'.

    man mv

    ciao
    slack? smack!

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2002
    Messaggi
    1,202
    Se può esserti utile, con questo comando ottieni il numero di livelli dell'albero (devi darlo tutto su una riga sola).

    codice:
    max=0; ls -R . | egrep ^'./' | while read riga; do zac=`echo $riga | sed -e "s/\///g"`; 
    let n=${#riga}-${#zac}; if [[ "$n" -gt "$max" ]]; then max=$n; echo $max; fi; done;
    L'ultimo numero che ti esce sarà quindi anche il numero di slash che dovrai mettere nel for per raggiungere l'ultimo livello.
    Ad esempio se ti esce "3" come ultimo numero, il comando ricorsivo sarà:

    codice:
    for i in */*/*/*; do mv "$i" `echo $i | tr -s 'à' 'a'`; done
    Così modifichi i file nell'ultimo livello di directory.
    Poi ridai il comando togliendo uno slash, e così via...

    A te automatizzare tutto.

    Debian GNU/Linux sid
    Publishing a theory should not be the end of one's conversation with the universe, but the beginning. (Eric S. Raymond)
    Kernel 2.6.14-ck1

  5. #5
    perchè invece di ammazzarti con mv non usi rename?

    $ rename "à" "a" *


    Ci sono cose che non si possono sapere. Per tutto il resto c'è man

    Prima di fare domande stupide: 1) googla 2) leggi le manpages 3) sparati.

  6. #6
    A me servirebbe eseguire questo operazione molte volte, per cui pensavo di fare un script di questo tipo:
    codice:
    #!/bin/sh
    
    # per per eliminare caratteri:
    
    for i in *; do mv "$i" `echo $i | tr -d '"'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '''`; done 2>/dev/null
    E così molte volte.
    Però, se faccio così, fa casino, sostituisce cose che non deve sostituire... (sono almeno 25 righe così).
    Come dovrei fare per "concatenare" tutte le sostituzioni, magari in un unico ciclo di for?

    Oppure,lasciando 25 righe così, come devo fare per farlo funzionare decentemente?

    Ho inserito una riga per ogni carattere da sostituire, e, per esempio, se ho un file "arrivò.txt" ed eseguo lo script, mi diventa "arrivao.txt"...
    Mentre se eseguo "separatamente" la riga per sostituire il carattere "ò" funziona bene.

    Grazie,
    Sergej
    :: Il Deposito
    Canti di protesta politica e sociale
    Archivio di testi e accordi

  7. #7
    Utente di HTML.it L'avatar di cacao74
    Registrato dal
    Jan 2005
    Messaggi
    2,570
    cacao74@winnie:~/tmp$ echo càcàò | tr -t 'àèéìòù' 'aeeiou'
    cacao

    ciao
    slack? smack!

  8. #8
    Dunque, c'è un problema.
    Se io ho un file ìr.txt ed eseguo il seguente comando da shell:
    codice:
    sergej[Prova]$ for i in *; do mv "$i" `echo $i | tr -s 'ì' 'i'`; done 2>/dev/null
    il file viene rinominato in ir.txt.

    Se invece eseguo lo script completo, mi trasforma il file in eir.txt.

    Ecco il codice completo:
    codice:
    #!/bin/sh
    
    # per per eliminare caratteri:
    
    for i in *; do mv "$i" `echo $i | tr -d '"'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '''`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '('`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d ')'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '{'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '}'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '\'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '?'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '&'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '='`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '~'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '!'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '%'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '<'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '>'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '*'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '&'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '&'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -d '&'`; done 2>/dev/null
    
    # script per sostituire i caratteri:
    
    for i in *; do mv "$i" `echo $i | tr -s 'à' 'a'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -s 'è' 'e'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -s 'é' 'e'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -s 'ì' 'i'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -s 'ò' 'o'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -s 'ù' 'u'`; done 2>/dev/null
    for i in *; do mv "$i" `echo $i | tr -s ' ' '_'`; done 2>/dev/null
    Dove è l'errore?

    Sergej
    :: Il Deposito
    Canti di protesta politica e sociale
    Archivio di testi e accordi

  9. #9
    Utente di HTML.it L'avatar di Ilmalcom
    Registrato dal
    Oct 2002
    Messaggi
    1,345
    Originariamente inviato da cacao74
    cacao74@winnie:~/tmp$ echo càcàò | tr -t 'àèéìòù' 'aeeiou'
    cacao

    ciao
    La soluzione qui postata dovrebbe fare al caso tuo, sostituisci tutte quelle righe con il comando singolo e vedi se funziona. Comunque quei 2>/dev/null vanno messi dopo il tr e prima del punto e virgola, non dopo il done... Dovrebbe funzionare anche come hai fatto tu, ma a livello logico è scorretto.

  10. #10
    Utente di HTML.it L'avatar di gianiaz
    Registrato dal
    May 2001
    Messaggi
    8,027
    e se avessi 2 files cosi:
    codice:
    àncora
    ancòra
    Tieni presente anche questo caso.

    Forse è il caso di usare un linguaggio di scripting tipo perl o python...

    ciao

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.