Hi,
alternative you can install the Satimage Scripting Additions
which provide lowercase and uppercase commands
Hi,
alternative you can install the Satimage Scripting Additions
which provide lowercase and uppercase commands
this keeps it all in the script
set foo to "foo"
set foo to do shellscript "echo " & foo & " | tr a-z A-Z"
I will use this in lots of places
Cheers, been a great help.
Here’s a subroutine which does the same. I got this code from this forum, unfortunately I forget who wrote it. Anyway, I tested the speed of this approach versus the do shell script approach using the “GetMilliSec subroutine and the Lotsa method”. Here’s the results.
Each test was run 500 times
the string I used in the test was “make this upper case.”
do shellscript “echo " & theString & " | tr a-z A-Z” → 11.368 secs
makeCaseUpper(theString) → 0.894 secs
Results: the subroutine is about 13 times faster than the do shell script command.
on makeCaseUpper(theString)
set UPPERCASE to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set lowercase to "abcdefghijklmnopqrstuvwxyz"
set AppleScript's text item delimiters to " "
set theWords to text items of theString as list
set AppleScript's text item delimiters to ""
set newList to {}
repeat with theWord in theWords
set chrs to characters of theWord
set Nchrs to count chrs -- get the number of characters
repeat with K from 1 to Nchrs
if (item K of chrs) is in lowercase then
set olc to offset of (item K of chrs) in lowercase
set item K of chrs to character olc of UPPERCASE
end if
end repeat
set end of newList to chrs as string
end repeat
set AppleScript's text item delimiters to " "
set theString to newList as string
set AppleScript's text item delimiters to ""
return theString
end makeCaseUpper
Hi regulus,
the Scripting Addition mentioned above is 25 times faster than the do shell script command
You could also do something like this:
on ToggleCase(theString)
set theString to ASCII number of theString
if theString ≥ 65 and theString ≤ 90 then set theString to ASCII character of (theString + 32)
if theString ≥ 97 and theString ≤ 122 then set theString to ASCII character of (theString - 32)
return theString
end ToggleCase
Not sure if it is faster than the other option, would be interesting to see some time tests.
on my Dual G5 at work it this script takes about 8 seconds to loop 10,000 times
on ToggleCase(theString)
set theString to ASCII number of theString
if theString ≥ 65 and theString ≤ 90 then set theString to ASCII character of (theString + 32)
return theString
end ToggleCase
set x to current date
set p to "make this upper case."
repeat with i from 1 to 10000
repeat with q from 1 to count of characters of p
set z to ToggleCase(character q of p)
end repeat
end repeat
set y to current date
set y to y - x
Interesting idea Jerome. I made a few changes to your code toget it to change the case to UPPER as this discussion requests. Here’s what I came up with.
set theString to "make this upper case"
set chrs to characters of theString
set toggleList to {}
repeat with i from 1 to (count of chrs)
my caseUPPER(item i of chrs)
set end of toggleList to result
end repeat
set toggleString to toggleList as string
on caseUPPER(chr)
set asciiNum to ASCII number of chr
if asciiNum ≥ 97 and asciiNum ≤ 122 then set chr to ASCII character of (asciiNum - 32)
return chr
end caseUPPER
So I ran the “GetMilliSec subroutine and the Lotsa method” again on this modified method and the one I posted earlier.
Each test was run 500 times
the string I used in the test was “make this upper case.”
Jerome’s modified method → 0.719 secs
my makeCaseUpper(theString) → 0.875 secs
Results: Jerome’s modified method is about 20% faster than my subroutine.
Cool idea Jerome!
Hi,
Your comparison testing is wrong. One script uses ‘do shell script’ while the other one doesn’t. If the user has to use the do shell script and change to uppercase instead of piping the output to ‘tr’, then what are the times?
gl,
For this particular problem, yet another approach using offsets (slim 15% advantage over Regulus’, didn’t test the others):
makeCaseUpper("Now is the time, perhaps, for all good men")
on makeCaseUpper(theString)
set UC to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set LC to "abcdefghijklmnopqrstuvwxyz"
set C to characters of theString
repeat with ch in C
if ch is in LC then set contents of ch to item (offset of ch in LC) of UC
end repeat
return C as string
end makeCaseUpper
kel, I’m not sure what you mean? Piping the output to tr changes to upper case and uses the “do shell script” command. Which 2 comparisons do you mean?
Hi regulus,
What I mean is that the op wanted to convert shell output to uppercase. The call to the shell takes time, so you have to include that in the comparison. I use Jon’s Commands’ ‘the ticks’ in these:
Script 1 (pipe output to ‘tr’:
set t1 to the ticks
set t to do shell script "echo hello | tr '[:lower:]' '[:upper:]'"
set t2 to the ticks
display dialog (t2 - t1)
t
Script 2 (convert output to all uppercase with AppleScript):
set t1 to the ticks
set t to uppercase (do shell script "echo hello")
set t2 to the ticks
display dialog (t2 - t1)
t
gl,
Oh kel, I see what you meant. You wanted me to get the string for my test from the shell, thus comparing TR to my subroutine. My thought was that you could avoid the shell all together with my subroutine whereas with TR you couldn’t… but if you do need the shell to get the string then I see your point.
So here’s the results with the test kel suggested. In these two tests the shell generated the string to be converted to upper case, then that string was sent to either TR or the subroutine. The results were vastly different. I alsoi ncluded the actual code for the test. Note, anyone that wants to run this test needs to first install the GetMilliSec scripting addition… I found it on this website.
– results of 500 tests → {9.645, 7.059, 1.366340841479}
The first result is for piping to TR. it took 9.645 secs
The second reasult is for piping the string to the subroutine → it took 7.059 secs for about a 36% improvement.
So the two conclusions for the subroutine are:
set Tests to RunTest() -- this kicks it off
----
on RunTest()
set lotsa to 500 -- the number of times the test will repeat
-- Any other preliminary values here.
-- Dummy loop to absorb a small observed time handicap in the first repeat.
repeat lotsa times -- warming up the engine.
end repeat
-- Test 1
set t to GetMilliSec
repeat lotsa times
-- test code or handler call here.
do shell script "echo hello | tr '[:lower:]' '[:upper:]'"
-- end of code fragment
end repeat
set t1 to ((GetMilliSec) - t) / 1000
-- Test 2
set t to GetMilliSec
repeat lotsa times
-- test code or handler call here.
my makeCaseUpper(do shell script "echo hello")
-- end of code fragment
end repeat
set t2 to ((GetMilliSec) - t) / 1000
-- Timings.
return {t1, t2, t1 / t2}
end RunTest
on makeCaseUpper(theString)
set UPPERCASE to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set lowercase to "abcdefghijklmnopqrstuvwxyz"
set AppleScript's text item delimiters to " "
set theWords to text items of theString as list
set AppleScript's text item delimiters to ""
set newList to {}
repeat with theWord in theWords
set chrs to characters of theWord
set Nchrs to count chrs -- get the number of characters
repeat with K from 1 to Nchrs
if (item K of chrs) is in lowercase then
set olc to offset of (item K of chrs) in lowercase
set item K of chrs to character olc of UPPERCASE
end if
end repeat
set end of newList to chrs as string
end repeat
set AppleScript's text item delimiters to " "
set theString to newList as string
set AppleScript's text item delimiters to ""
return theString
end makeCaseUpper
Hello
Is there a shell script command allowing the lower <> upper conversion for accented chars which are often used in non-English languages ?
Yvan KOENIG
Hi Yvan,
you could add accented characters manually to ‘tr’:
do shell script “echo ‘french accents: éèê - german umlauts:äöü - spanish characters: ñ …’ | tr [a-zéèêäöüñ] [A-ZÉÈÊÄÖÜÑ]]”
D.
Hi regulus,
Yes, that’s what i meant. I found it interesting also, that Satimage osax’ ‘uppercase’ was about two times faster than piping the output to ‘tr’. I wonder what the times would be if you test it in Terminal. I don’t know how to do that though.
gl,
Python will handle them. Check out the changeCase handler I posted (from the thread I mentioned earlier).
Thanks
I didn’t saw it (don’t lok at page 2)
Adding accented chars in the list by hand was a bit boring
Yvan KOENIG
I found this nice handler on a website, and I have often found it helpful. (I wish I could take credit.)
on changeCaseOfText(theText, theCaseToSwitchTo)
if theCaseToSwitchTo contains "lower" then
set theComparisonCharacters to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set theSourceCharacters to "abcdefghijklmnopqrstuvwxyz"
else if theCaseToSwitchTo contains "upper" then
set theComparisonCharacters to "abcdefghijklmnopqrstuvwxyz"
set theSourceCharacters to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
else
return theText
end if
set theAlteredText to ""
repeat with aCharacter in theText
set theOffset to offset of aCharacter in theComparisonCharacters
if theOffset is not 0 then
set theAlteredText to (theAlteredText & character theOffset of theSourceCharacters) as string
else
set theAlteredText to (theAlteredText & aCharacter) as string
end if
end repeat
return theAlteredText
end changeCaseOfText
For AppleScriptObjectiveC, i highly recommended ‘RegexAndStuffLib’ vom Shane Stanley. Please look at https://latenightsw.com/freeware/.