问题
Using Gimp 2.6.6 for MAC OS X (under X11) as downloaded from gimp.org.
I'm trying to automate a boring manual process with Script-Fu. I needed to parse the image file name to save off various layers as new files using a suffix on the original file name.
My original attempts went like this but failed because (string-search ...)
doesn't seem to be available under 2.6 (a change to the scripting engine?).
(set! basefilename (substring filename 0 (string-search "." filename)))
Then I tried to use this information to parse out the base file name using regex but (re-match-nth ...)
is not recognized either.
(if (re-match "^(.*)[.]([^.]+)$" filename buffer)
(set! basefilename (re-match-nth orig-name buffer 1))
)
And while pulling the value out of the vector ran without error, the resulting value is not considered a string when it is passed into (string-append ...)
.
(if (re-match "^(.*)[.]([^.]+)$" filename buffer)
(set! basefilename (vector-ref buffer 1))
)
So I guess my question is, how would I parse out the base file name?
回答1:
Context
GIMP 2.6.6 Windows Vista SP2
Goal
Extract the basename of the original filename without its extension.
Symptom
Error: eval: unbound variable: re-match-nth
Possible suggestion
GIMP menu "Filters" > "Script-Fu" > "Console"
In the input box, paste the following Script-Fu definition of function then hit the ENTER key:
(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
To test the function, enter:
(filename-basename "screen.xcf")
The Script-Fu Console answers:
"screen"
回答2:
Not really a correct solution:
> (filename-basename "this.is.a.long.filename.jpg")
"this"
A better implementation:
(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)
)
)
)
回答3:
My version splits the filename (f) into parts delimited by separator ("." in this case); drops last part; and re-combines them with separator again
(define (pc-drop-extension f)
(unbreakupstr (butlast (strbreakup f ".")) ".") )
so
(pc-drop-extension "ab.cd.efi") -> "ab.cd"
and
(pc-drop-extension "ab/cd.ef/ghi.jkl.mno") -> "ab/cd.ef/ghi.jkl"
回答4:
Many thanks philcolbourn for pointing out a "simple" way to do this. Unfortunately, the butlast function is deprecated: http://www.gimp.org/docs/script-fu-update.html#deprecated
Here is philcolbourn's version with the suggested replacement:
(define (drop-extension filename)
(unbreakupstr (reverse (cdr (reverse (strbreakup filename ".")))) ".")
)
回答5:
As in Gimp 2.8 "gimp-image-get-uri" has to be used to get the filename of a JPG file, but gimp-image-get-uri delivers the complete path, I used this function to extract just the name of the pic (without the suffix ".jpg"):
(let* (
(uriname (car (gimp-image-get-uri IMAGE)))
(basename (car (reverse (strbreakup (car (strbreakup uriname ".")) "/"))))
...
)
...
)
回答6:
For those looking for a true string-replace functionality, here is a function I wrote for use 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 "")
)
)
来源:https://stackoverflow.com/questions/1386293/how-to-parse-out-base-file-name-using-script-fu