Pagina 1 di 1

[RISOLTO][BASH] Confronto di due file

Inviato: dom 14 giu 2009, 16:52
da Delcaran Lëdeloth
Per un esame devo realizzare uno script bash che cambi le estensioni dei file (puro cambiamento del nome, nessuna conversione). È tutto pronto e funzionante, a parte un piccolo dettaglio che mi manda in bestia. Ecco lo spezzone di codice che mi da problemi:

Codice: Seleziona tutto

for nomefile in $guardia_for # esegue la rinomina sui file
# il for considera gli elementi della lista come separati dallo spazio: ogni parola viene considerata come un file diverso...
   do  # rinomina, se possibile, il file $nomefile con la nuova estensione $est_dest
       temp_name="$temp_name $nomefile" # concateno i nomi (con questo metodo aggiungo uno spazio prima del nome del file)
       temp_est="${temp_name:(-${#est_orig})}"
       echo "$temp_est == $est_orig"
       if [ "$temp_est"=="$est_orig" ] # sembra che restituisca sempre vero...
          then
                temp_name=${temp_name#" "} # rimuovo lo spazio iniziale
                mv "$temp_name" "${temp_name%.$est_orig}.$est_dest"
                temp_name=""
          else #non finisce con estensione, bisogna iterare
                echo "$temp_name non ha estensione"
                continue
       fi
done
Il problema si presente nell'if. Quando arrivo in questa parte del programma, $nomefile contiene la lista dei file da processare. Il problema è che la bash considera come separatore per le liste il carattere "spazio", e quindi i nomi di file composti da più parole vengono considerati come file diversi, un file per parola. L'if deve verificare se la parola in esame termina effettivamente con un'estensione. Se così è, allora è un file e va rinominato, altrimenti a questa parola si aggiungono le parole seguenti fino a completare il nome del file. Il guaio è che il confronto non funziona. Devo confrontare semplicemente le due stringhe $temp_est e $est_orig e vedere se sono uguali, ma anche se sono diversi il risultato è sempre e comunque che sono uguali. Le stringhe sono corrette e contengono i caratteri appropriati. L'unico problema è nell'if... Qualcuno può suggerirmi un metodo per confrontare decentemente le stringhe di caratteri in bash??? Ho letto e riletto Advance Bash Scripting ma non ho risolto nulla :(

Re: [BASH] Confronto di due file

Inviato: dom 14 giu 2009, 17:41
da raffaele181188
Avevo scritto una cosa ma poi, rileggendo, mi è sorto il dubbio che non c'entrasse niente...
Qui è spiegato un modo per risolvere in caso di spazi nei nomi, vedi se ti può aiutare

Re: [BASH] Confronto di due file

Inviato: dom 14 giu 2009, 18:19
da Mario Vanoni
Non trovo da nessuna parte che due
${Shell Parameter Expansion}
siano impilabili (can be nested).

Forse devi farlo in due passi.

temp_est="${temp_name:(-${#est_orig})}"

Re: [BASH] Confronto di due file

Inviato: dom 14 giu 2009, 18:28
da d4z_c0nf
Delcaran Lëdeloth ha scritto:Per un esame devo realizzare uno script bash che cambi le estensioni dei file (puro cambiamento del nome, nessuna conversione). È tutto pronto e funzionante, a parte un piccolo dettaglio che mi manda in bestia. Ecco lo spezzone di codice che mi da problemi:

Codice: Seleziona tutto

for nomefile in $guardia_for # esegue la rinomina sui file
# il for considera gli elementi della lista come separati dallo spazio: ogni parola viene considerata come un file diverso...
   do  # rinomina, se possibile, il file $nomefile con la nuova estensione $est_dest
       temp_name="$temp_name $nomefile" # concateno i nomi (con questo metodo aggiungo uno spazio prima del nome del file)
       temp_est="${temp_name:(-${#est_orig})}"
       echo "$temp_est == $est_orig"
       if [ "$temp_est"=="$est_orig" ] # sembra che restituisca sempre vero...
          then
                temp_name=${temp_name#" "} # rimuovo lo spazio iniziale
                mv "$temp_name" "${temp_name%.$est_orig}.$est_dest"
                temp_name=""
          else #non finisce con estensione, bisogna iterare
                echo "$temp_name non ha estensione"
                continue
       fi
done
Il problema si presente nell'if. Quando arrivo in questa parte del programma, $nomefile contiene la lista dei file da processare. Il problema è che la bash considera come separatore per le liste il carattere "spazio", e quindi i nomi di file composti da più parole vengono considerati come file diversi, un file per parola. L'if deve verificare se la parola in esame termina effettivamente con un'estensione. Se così è, allora è un file e va rinominato, altrimenti a questa parola si aggiungono le parole seguenti fino a completare il nome del file. Il guaio è che il confronto non funziona. Devo confrontare semplicemente le due stringhe $temp_est e $est_orig e vedere se sono uguali, ma anche se sono diversi il risultato è sempre e comunque che sono uguali. Le stringhe sono corrette e contengono i caratteri appropriati. L'unico problema è nell'if... Qualcuno può suggerirmi un metodo per confrontare decentemente le stringhe di caratteri in bash??? Ho letto e riletto Advance Bash Scripting ma non ho risolto nulla :(
if [ "$a" = "$b" ]

Re: [BASH] Confronto di due file

Inviato: dom 14 giu 2009, 18:34
da Mario Vanoni
Rocco scusa

man bash

string1 == string2
True if the strings are equal. = may be used in place of == for strict POSIX compliance.

Re: [BASH] Confronto di due file

Inviato: dom 14 giu 2009, 18:38
da d4z_c0nf
Mario Vanoni ha scritto:Rocco scusa

man bash

string1 == string2
True if the strings are equal. = may be used in place of == for strict POSIX compliance.
Mario figurati, ma dipende dalla "notazione".
Quella originale dice [[ string1 == string2 ]], e come vedi c'è lo spazio cosa che comunque lui non ha messo!
Poi c'è una versione delle condizioni semplificata (e standardizzata POSIX), che permette di usare una sola parentesi e un solo (ma anche due) uguale, [ string1 = string2 ],
Ma c'è sempre lo spazio, spazio che anche tu hai "citato". Gl'ho dato la versione corretta della notazione che ha scelto.
rock

Re: [BASH] Confronto di due file

Inviato: dom 14 giu 2009, 20:34
da Delcaran Lëdeloth
Mario Vanoni ha scritto:Non trovo da nessuna parte che due
${Shell Parameter Expansion}
siano impilabili (can be nested).

Forse devi farlo in due passi.

temp_est="${temp_name:(-${#est_orig})}"
Non è che impilo, semplicemente concateno due stringhe :) questa parte funziona ;)
Qui è spiegato un modo per risolvere in caso di spazi nei nomi, vedi se ti può aiutare
Mi ha aiutato, grazie mille :D avevo provato tutte le sintassi di confronto, ma mi dava sempre e comunque lo stesso errore...
Ora ho risolto tutto, ecco la funzione definitiva!

Codice: Seleziona tutto

function rename_extensions () {
  if [[ $1 == 0 ]] # verifica se e' stata richiesta la ricorsione nelle directory
    then
		for nomefile in *.$est_orig # esegue la rinomina sui file
		do  # rinomina, se possibile, il file $nomefile con la nuova estensione $est_dest
			 mv "$nomefile" "${nomefile%.$est_orig}.$est_dest"
		done
    else # effettua ricorsione
		find . -name "*.$est_orig" -print0 | while read -r -d $'\0' f; do
		  mv "$f" "${f%.$est_orig}.$est_dest"
		done
  fi
}