Come analizzare fuori il nome del file di base utilizzando Script-Fu
Domanda
Usando Gimp 2.6.6 per Mac OS X (X11 sotto) come scaricato da gimp.org.
Sto cercando di automatizzare un processo manuale noioso con Script-Fu. Avevo bisogno di analizzare il nome del file immagine per salvare off vari strati come nuovi file utilizzando un suffisso sul nome del file originale.
I miei tentativi originali sono andati come questo, ma non è riuscito a causa (string-search ...)
non sembra essere disponibile sotto 2.6 (una modifica al motore di scripting?).
(set! basefilename (substring filename 0 (string-search "." filename)))
Poi ho cercato di usare questo informazioni per analizzare fuori il nome del file di base utilizzando espressioni regolari, ma (re-match-nth ...)
non viene riconosciuto sia.
(if (re-match "^(.*)[.]([^.]+)$" filename buffer)
(set! basefilename (re-match-nth orig-name buffer 1))
)
E mentre si tira fuori il valore del vettore corse senza errori, il valore risultante non è considerato una stringa quando viene passato (string-append ...)
.
(if (re-match "^(.*)[.]([^.]+)$" filename buffer)
(set! basefilename (vector-ref buffer 1))
)
Quindi credo che la mia domanda è, come faccio analizzare fuori il nome file di base?
Soluzione
Contesto
GIMP 2.6.6 Windows Vista SP2
Obiettivo
Estrarre il nome base del nome del file originale, senza la sua estensione.
Sintomo
Errore: eval: variabile non legato: re-match-esimo
Possibili suggerimento
menu di GIMP " Filtri "> " Script-Fu "> " Console "
Nella casella di input, incollare la seguente definizione Script-Fu della funzione poi ha colpito la Invio Chiave:
(define (filename-basename orig-name)
(car (strbreakup orig-name "."))
; Nimmzo 09/09/30: the string split function strbreakup is defined
; in the compatibility file from SIOD to TinyScheme:
; C:\Program Files\GIMP\share\gimp\2.0\scripts\script-fu-compat.init
) ; end filename-basename
Per verificare la funzione, digitare:
(filename-basename "screen.xcf")
Le risposte Script-Fu Console:
"screen"
Altri suggerimenti
Non è davvero una soluzione corretta:
> (nome del file-nome base "this.is.a.long.filename.jpg")
"questo"
Una migliore applicazione:
(define (morph-filename orig-name new-extension)
(let* ((buffer (vector "" "" "")))
(if (re-match "^(.*)[.]([^.]+)$" orig-name buffer)
(string-append (substring orig-name 0 (car (vector-ref buffer 2))) new-extension)
)
)
)
La mia versione divide il nome del file (f) in parti delimitate da separatore (in questo caso ""); gocce ultima parte; e re-combina con separatore di nuovo
(define (pc-drop-extension f)
(unbreakupstr (butlast (strbreakup f ".")) ".") )
così
(pc-drop-extension "ab.cd.efi") -> "ab.cd"
e
(pc-drop-extension "ab/cd.ef/ghi.jkl.mno") -> "ab/cd.ef/ghi.jkl"
Molte grazie philcolbourn per indicare un modo "semplice" per fare questo. Purtroppo, la funzione butlast è deprecata: http://www.gimp.org/docs/script-fu-update .html # deprecato
Questa è la versione di philcolbourn con la sostituzione suggerita:
(define (drop-extension filename)
(unbreakupstr (reverse (cdr (reverse (strbreakup filename ".")))) ".")
)
Come in Gimp 2.8 "gimp-image-get-uri" deve essere utilizzato per ottenere il nome di un file JPG, ma gimp-image-get-uri batte il percorso completo, ho usato questa funzione per estrarre solo il nome della foto (senza il suffisso ".jpg"):
(let * (
(Uriname (auto (gimp-image-get-uri IMMAGINE)))
(Nome base (auto (reverse (strbreakup (auto (strbreakup uriname "")) "/"))))
...
)
...
)
Per chi cerca una vera funzionalità di stringa-sostituzione, qui è una funzione che ho scritto per l'uso in Script Fu
(define (string-replace strIn strReplace strReplaceWith)
(let*
(
(curIndex 0)
(replaceLen (string-length strReplace))
(replaceWithLen (string-length strReplaceWith))
(inLen (string-length strIn))
(result strIn)
)
;loop through the main string searching for the substring
(while (<= (+ curIndex replaceLen) inLen)
;check to see if the substring is a match
(if (substring-equal? strReplace result curIndex (+ curIndex replaceLen))
(begin
;create the result string
(set! result (string-append (substring result 0 curIndex) strReplaceWith (substring result (+ curIndex replaceLen) inLen)))
;now set the current index to the end of the replacement. it will get incremented below so take 1 away so we don't miss anything
(set! curIndex (-(+ curIndex replaceWithLen) 1))
;set new length for inLen so we can accurately grab what we need
(set! inLen (string-length result))
)
)
(set! curIndex (+ curIndex 1))
)
(string-append result "")
)
)