Using AppleScript in Automator for replacing characters - applescript

I want to create service in Apple Automator to replace the characters to another ones. For instance, if I want to transform a phone number format:
+X(XXX)XXX-XX-XX => XXXXXXXXXX
Thanks.

Here is a Simple applescript code you can put in automator and it returns the output as a complete number = XXXXXXXXXX
on run {input, parameters}
set inputNumber to input as text
set outputNumber to ""
if inputNumber begins with "+" then
-- The Number begins with a + so convert number
set noParts to the number of words of inputNumber
repeat with cPart from 3 to noParts
set outputNumber to outputNumber & word cPart of inputNumber
end repeat
end if
return outputNumber
end run
Hope this helps!

Related

Get text of selected field code in Microsoft Word using AppleScript

I'm making a Automator to jump from citation in Word to the reference software(Zotero). But I can't find a AppleScript to extract text of selected field code (the first step).
The field code in Word is
ADDIN ZOTERO_ITEM CSL_CITATION {"citationID":"AFUiwuqi","properties":{"formattedCitation":"[1]","plainCitation":"[1]","noteIndex":0},"citationItems":[{"id":9752,"uris":["http://zotero.org/users/6410528/items/YYTRWPHH"],"itemData":{"id":9752,"type":"article-journal","container-title":"Nature","DOI":"10.1038/s41586-019-1737-7","ISSN":"0028-0836, 1476-4687","issue":"7782","page":"324-329","title":"Controlled flight of a microrobot powered by soft artificial muscles","volume":"575","author":[{"family":"Chen","given":"Yufeng"},{"family":"Zhao","given":"Huichan"},{"family":"Mao","given":"Jie"},{"family":"Chirarattananon","given":"Pakpong"},{"family":"Helbling","given":"E. Farrell"},{"family":"Hyun","given":"Nak-seung Patrick"},{"family":"Clarke","given":"David R."},{"family":"Wood","given":"Robert J."}],"issued":{"date-parts":[["2019",11,14]]}}}],"schema":"https://github.com/citation-style-language/schema/raw/master/csl-citation.json"}
Here is the script process:
Extract text from selected field code in Word (This is the question)
Get the uris text(http://zotero.org/users/6410528/items/YYTRWPHH)
Get the item-codes (YYTRWPHH).
Open url (zotero://select/library/items?itemKey=YYTRWPHH)
Now I use VBA to extract field code text, see below. But in this way, the file will be changed. So I want to do this via AppleScript.
Sub GetFiledsCodes()
Dim myRange As Range, myCodes As String
Set myRange = Selection.Range
With myRange
If .Fields.Count = 0 Then
MsgBox "No Code!", vbInformation
Exit Sub
Else
.Fields.Update
.TextRetrievalMode.IncludeFieldCodes = True
.TextRetrievalMode.IncludeHiddenText = True
myCodes = .Text
myCodes = VBA.Replace(myCodes, Chr(19), "{")
myCodes = VBA.Replace(myCodes, Chr(21), "}")
.SetRange .End, .End
.InsertAfter myCodes
.Font.Name = "Times New Roman"
.Font.Size = 12
.Cut
End If
End With
End Sub
PS:
Here is my process in Automator(it can work but using VBA):
Run AppleScript
on run {input, parameters}
tell application "Microsoft Word" to activate
tell application "Microsoft Word"
run VB macro macro name "GetFiledsCodes"
delay 0.5
end tell
return input
end run
Get contents from clipboard
Extract URLs from Text
Filter Paragraphs begin with http://zotero.org/users/
Copy to Clipboard
Run AppleScript
set myStr to do shell script "pbpaste"
tell application "Zotero" to activate
set AppleScript's text item delimiters to "
"
set myList to every text item of myStr
set zoterocode to ""
set codes to ""
repeat with j from 1 to the length of myList
set itemValue to item j of myList
set zoterocode to (do shell script "sed -E 's#http://zotero.org/users/[0-9]+/items/##g' <<< " & itemValue)
if j = 1 then
set codes to zoterocode
else
set codes to codes & "," & zoterocode
end if
end repeat
tell application "System Events"
key code 18 using {command down, control down, option down}
delay 0.5
set collectionKey to do shell script "pbpaste"
if collectionKey = myStr then
set theurl to "zotero://select/library/items?itemKey=" & codes
else
set theurl to collectionKey & "/items?itemKey=" & codes
end if
open location theurl
end tell
That helps a lot. Okay, so this isn't a turnkey solution for your question but I don't think you really need that as you'd probably end up having to tell me more about how this app works than is really necessary. So this script focuses on your initial question about getting the field codes/result ranges from a merge document.
I put together a simple mail merge consisting of labels and a data file with 8 records, each of which have 5 fields: {"«LastName»", "«JobTitle»", "«Company»", "«City»", "«Web»"}. The latter is the key field.
Basically, the script runs through the data merge document and cycles first through its fields, then the web field, and finally the web addresses.
Based on your script, I can't really determine what you are doing with each address so it finishes by collecting just the final part of each address in a list. The obscure parts for me are the pbpastes, the codes and the whole System Events block. This area would need tweaking.
Incidentally, it's quite likely that you can avoid some of the shell scripts but I can't say how yet. Obviously the script has some redundancies and could be further refined but I think it demonstrates how to extract the information you need. Take a look at it and let me know what issues there are that need addressing.
tell application "Microsoft Word"
set d1 to document "cardo_labels.docx"
set fContents to {} -- list of mergefield
set fResRange to {} -- list of result range, i.e. field merge data
repeat with x from 1 to (count of fields of d1)
set fcs to content of field code of field x of d1 --> " MERGEFIELD LastName "
set frr to content of result range of field x of d1 --> "Smith"
if fcs is not " NEXT " then -- ignore «Next Record»
set end of fContents to fcs
set end of fResRange to frr
end if
end repeat
--> single record example
fContents --> {" MERGEFIELD LastName ", " MERGEFIELD JobTitle ", " MERGEFIELD Company ", " MERGEFIELD City ", " MERGEFIELD Web "}
fResRange --> {"Smith", "President", "Acme Screw & Gear", "Metz", "http://zotero.org/users/1234/items/smith-metz"}
-- NB when not displaying 'merged data', fResRange will appear thusly: {"«LastName»", "«JobTitle»", "«Company»", "«City»", "«Web»"}
set webList to {}
repeat with y from 1 to (count of fResRange)
if item y of fResRange begins with "http://zotero.org/users/" then
set end of webList to (item y of fResRange)
end if
end repeat
--> {"http://zotero.org/users/1234/items/smith-metz"}
--> {"http://zotero.org/users/1234/items/smith-metz", "http://zotero.org/users/4222/items/branson-metz", "http://zotero.org/users/3236/items/house-metz", "http://zotero.org/users/3342/items/kurtz-london", "http://zotero.org/users/12345/items/jones-london"}
set urlPiece to {}
set AppleScript's text item delimiters to "/"
repeat with z in webList
set end of urlPiece to last text item of z
end repeat
-- contents of z
--> "http://zotero.org/users/1234/items/smith-metz"
set AppleScript's text item delimiters to ""
urlPiece
--> {"smith-metz"}
--> {"smith-metz", "jones-saopaolo", "branson-metz", "house-metz", "kurtz-london", "jones-london"}
end tell
Thanks to ideas from #Mockman.
Combining with the selection, here is the way to extract text from selected field code via AppleScript:
tell application "Microsoft Word"
tell selection
set fcs to content of field code of field of text object
end tell
end tell
fcs

Find text from a file and set it as a variable in applescript?

I am trying to build a script that sends me updates and notifications from cex.io. Please keep on reading below, so I may guide you until the point I have trouble with.
The first simple script in this operation goes to cex.io's trading page for BTC/GHS. It records ands saves the text to a file every 4 seconds. It works great. It doesn't need to have safari refresh because the site pushes info to the browser live.
repeat
set the webpage_content to ""
tell application "Safari" to set the webpage_content to the text of document 1
set theText to webpage_content
set a to "Macintosh HD:Users:PRIVATE:Desktop:CEX:"
set theFile to (open for access file ((a) & "CEXRaw") with write permission)
write theText to theFile
close access theFile
delay 4
end repeat
-
And it returns this in a main file every 4 seconds: (note I cut off a chunk from the bottom and the top of the file, because they are unimportant)
GHS:
0.05233439
BTC:
0.00000223
NMC:
0.00002939
LTC:
0.00000000
GHS/BTC
0.02362958 LTC/BTC
0.02438131 NMC/BTC
0.00597565 GHS/NMC
3.96951800 BF1/BTC
1.67000000 Fund Account
GHS/BTC
Last price:
0.02362958
Daily change:
-0.00018042
Today's open:
0.02381000
24h volume:
73812.35539255
-
I now need an applescript to read that file, and return wanted values. But I'm lost on how to write it.
It needs to find the number under BTC, and set it as a variable.
It needs to find the number under GHS, and set it as a variable.
It needs to find the number under Last Price, and set it as a variable.
If anyone could script that really quick for me, or tell me how to do it, that would be amazing. Thank you so much!
Well, if those values will always be in the same paragraph counts, you could just pull them by line number.
set theCEXRaw to read file "Macintosh HD:Users:PRIVATE:Desktop:CEX:CEXRaw"
set theGHS to paragraph 2 of theCEXRaw
set theBTC to paragraph 4 of theCEXRaw
set thePRICE to paragraph 17 of theCEXRaw
You'd need to adjust the paragraph numbers. But, assuming that paragraph numbers aren't reliably consistent, in pure Applescript, you'd use Applescript's Text Item Delimiters.
set theCEXRaw to read file "Macintosh HD:Users:PRIVATE:Desktop:CEX:CEXRaw"
set AppleScript's text item delimiters to {("GHS:
"), ("BTC:
"), ("Last price:
")}
set theCEXRaw to text items of theCEXRaw
set theGHS to paragraph 1 of item 2 of theCEXRaw
set theBTC to paragraph 1 of item 3 of theCEXRaw
set thePRICE to paragraph 1 of item 4 of theCEXRaw
Note that the three delims include a return character inside the quotes. You will want to capture the old delimiter first, so you can restore it, and hopefully you can do the setting of the delimiter outside your repeat loop to save juice.
You could also use do shell script with sed or grep to strip each value.
You could get those values using the offset which searches a string for a substring and returns it's character position.
eg, set pos to the offset of "world" in "hello world" -- returns 7
Here is a solution that uses this principal to find your values and convert them into the Applescript floating point type Number
property line_delimiter : linefeed -- OR return OR return & linefeed pending your data
set results to "GHS:
0.05233439
BTC:
0.00000223
NMC:
0.00002939
LTC:
0.00000000
Last price:
0.02362958"
processCEX(results)
on processCEX(in_text)
set btc_val to searchNumberValueLine("BTC:" & line_delimiter, in_text)
set ghs_val to searchNumberValueLine("GHS:" & line_delimiter, in_text)
set last_price_val to searchNumberValueLine("Last price:" & line_delimiter, in_text)
display dialog ("btc = " & btc_val & return & "ghs = " & ghs_val & return & " last price = " & last_price_val)
end processCEX
on searchNumberValueLine(key_name, input_str)
set start_index to the offset of key_name in input_str
if (start_index is not 0) then
set input_str to text (start_index + ((length of key_name))) thru -1 of input_str
set end_index to the offset of line_delimiter in input_str
if (end_index is 0) then
return input_str as number
else
return (text 1 thru (end_index - 1) of input_str) as number
end if
else
return -1
end if
end searchNumberValueLine
Also i'd recommend against writing to a text file if you don't need to, to avoid any file io issues when reading the same file from a different script, given you are modifying it every 4 seconds.
You could change your code to something like this:
repeat
set the webpage_content to ""
tell application "Safari" to set the webpage_content to the text of document 1
processCEX(webpage_content)
delay 4
end repeat

Find and replace in Excel 2011 using Applescript

I was wondering if anyone could help me. I'm trying to find and replace blank spaces in an excel workbook. I want it to search the current sheet I'm on in a workbook, find all instances of "" and replace it with " ".
Does anyone happen to know how to do this?
With Applescript:
searchAndReplaceTextInCells("hello", "world")
on searchAndReplaceTextInCells(search_str, replace_str)
tell application "Microsoft Excel"
set search_range to range "A:Z"
set all_found_ranges to {} -- store for the ranges, to manipulate after searching
set found_range to ""
set counter to 0
try
set found_range to find search_range what search_str with match case
on error
log ("No matches found")
end try
if (found_range is not "") then
set first_cell_address to (get address of the cells of found_range) -- we use this to break our loop
repeat while true
set counter to counter + 1
copy found_range to end of all_found_ranges
-- Now look for next result
set found_range to find next search_range after found_range
set cell_address to (get address of the cells of found_range)
if (cell_address = first_cell_address) then
-- have looped around so we are finished!
exit repeat
end if
end repeat
end if
-- walk all the ranges found and do the string replacing
repeat with r in all_found_ranges
set value of r to my replace_chars(the value of r, search_str, replace_str)
end repeat
log ("found and replaced " & counter & " items")
end tell
end searchAndReplaceTextInCells
on replace_chars(this_text, search_string, replacement_string)
set my text item delimiters to the search_string
set the item_list to every text item of this_text
set my text item delimiters to the replacement_string
set this_text to the item_list as string
set my text item delimiters to ""
return this_text
end replace_chars
How about Command + F, and hit the Replace button to give you this:
Have you tried the following:
replace range targetRange what searchStr replacement replaceStr
This should be rather straight forward replacement statement.

applescript transforming a list into a txt file

I'm trying to write all the song names my iTunes to a txt document. The first issue I had was that I can't seem to correctly loop the operation. Here is my test case with the first 15 songs in my iTunes:
tell application "TextEdit"
make new document
end tell
tell application "iTunes"
set trNameID1 to name of track 1
set trNameID2 to name of track 2
set trNameID3 to name of track 3
set trNameID4 to name of track 4
set trNameID5 to name of track 5
set trNameID6 to name of track 6
set trNameID7 to name of track 7
set trNameID8 to name of track 8
set trNameID9 to name of track 9
set trNameID10 to name of track 10
set trNameID11 to name of track 11
set trNameID12 to name of track 12
set trNameID13 to name of track 13
set trNameID14 to name of track 14
set trNameID15 to name of track 15
tell application "TextEdit"
set text of document 1 to {trNameID1 & "
", trNameID2 & "
", trNameID3 & "
", trNameID4 & "
", trNameID5 & "
", trNameID6 & "
", trNameID7 & "
", trNameID8 & "
", trNameID9 & "
", trNameID10 & "
", trNameID11 & "
", trNameID12 & "
", trNameID13 & "
", trNameID14 & "
", trNameID15} as text
end tell
end tell
When I try to loop it, the txt document only contains the last song name, for instance:
tell application "TextEdit"
make new document
end tell
tell application "iTunes"
set trNum to 1
repeat 15 times
set trNameID to name of track (trNum)
tell application "TextEdit"
set text of document 1 to trNameID & "
"
end tell
end repeat
end tell
This will only output the fifteenth song's name onto the txt document.
I realize that this may be very basic, but I have literally been using applescript for about 48 hours, and I can't seem to figure this out. I would like all of the song names to be in a txt document so I can read and analyze the strings in c++. Does anyone have any ideas?
Also, I'm not sure if there is a way, in AppleScript, to look at the entire iTunes library and see the last song, record that song's id in iTunes, and then make a repeat loop that goes through that id. This way the loop would work for exactly the number of songs that are in the library.
Any ideas would be very much appreciated!
You don't really need a repeat loop at all. You can get track names directly from iTunes. You get it in list format so we just convert that list into a string separating the list items with a return character. Then we write it to TextEdit. So this code optimizes #Michele Percich's code by eliminating the repeat loop and using applescript's text item delimiters to convert the list to a string for use in TextEdit.
tell application "iTunes"
set trackNames to name of every track in (first playlist whose special kind is Music)
end tell
set text item delimiters to return
set trackNames to trackNames as text
set text item delimiters to ""
tell application "TextEdit"
make new document
set text of document 1 to trackNames
end tell
You need to increment the value of trNum variable at the end of your repeat loop:
set trNum to trNum + 1
Or better use a different repeat syntax:
repeat with trNum from 1 to 15
And also to add (and not replace) the track name to the document:
set text of document 1 to text of document 1 & trNameID & return
However, this probably is a better way to do what you want:
tell application "iTunes"
set trackList to ""
set allTracks to every track in (first playlist whose special kind is Music)
repeat with currentTrack in allTracks
set trNameID to name of currentTrack
set trackList to trackList & trNameID & return
end repeat
end tell
tell application "TextEdit"
make new document
set text of document 1 to trackList
end tell
i see you all use the:
tell application "TextEdit"
make new document
set text of document 1 to trackNames
end tell
command
You can use a faster way:
set textlocation to "/users/yourusername/desktop/test.txt"
set Line_1 to "Hello this is line one, if you want more lines just copy > this script and change the variables."
do shell script "echo " & quoted form of Line_1 & " >> " & quoted form of textlocation
You can see in the script the 2 ">>" signs, this will add each textline in a new line in a txt file.
If there is only one ">" the text will replace the other text.
Here is an example:
First with 2 ">>" lines
do shell script "echo Hey this is one line. >> /Users/Yourusername/desktop/Add.txt"
do shell script "echo And this is the second one. >> /Users/Yourusername/desktop/Add.txt"
This script will make a txt file like this:
Hey this is one line.
And this is the second one.
Now with 2 ">" lines
do shell script "echo Hey this is one line > /Users/Zl109819/desktop/Add.txt"
do shell script "echo And this is the second one > /Users/Zl109819/desktop/Add.txt"
This script will make a txt file like this:
And this is the second one.

How do I create an AppleScript to loop through a BBEdit document and move a "-" from the end of a number to the beginning?

I have a dirty report file that contains improperly formatted negative numbers. The ultimate goal is to import these to Excel for analysis. I am using BBEdit to clean the report before importing into Excel. I would like to create an apple script to loop through the report and move the "-" from the back of the number to the front.
Dirty Report Example Rows:
B-EXCAL 02 3684 2.0000- 49.02- 108.00- 58.98- 54.6-
B-MISMH 09-3300 33.0000 722.91 1353.00 630.09 46.6
Desired output:
B-EXCAL 02 3684 -2.0000 -49.02 -108.00 -58.98 -54.6
B-MISMH 09-3300 33.0000 722.91 1353.00 630.09 46.6
I have JavaScript and VBScript experience so I imaging the script working something like this psudo script:
Get contents of current window from BBEdit
for each word in contents
if char(len(word)) = "-"
newWord = "-" + rightTrim(word, 1)
replace(word, newWord)
end if
end for
end
This is my first experience with AppleScript and I am at a complete loss.
Thanks for the help/
I'm not sure you need AppleScript. Will BBEdit's find/replace window work for this? Try the following:
Find: ([0-9\.]+)\-
Replace: \-\1
"Grep" and "Wrap around" should be the only things selected below the "Replace" text area. Then click "Replace All."
If you need to do it to a bunch of reports at once, use the same find/replace patterns with multi file search. If I'm not understanding your question correctly, let me know, but I think you can get this done without AppleScript.
Try this. I'm assuming you can get the text from bbedit (or wherever) into applescript as the variable "originalText". Then you'll have to put the "fixedText" back wherever it belongs. NOTE: in my code I assume the "tab" character separates the words/columns in each line of the origText as Michael J. Barber has it currently formatted. If it is another character (like a space character) then you will have to change the word tab in the code to space.
set originalText to "B-EXCAL 02 3684 2.0000- 49.02- 108.00- 58.98- 54.6-
B-MISMH 09-3300 33.0000 722.91 1353.00 630.09 46.6"
set fixedText to fixNegativeSigns(originalText)
on fixNegativeSigns(theText)
set listText to paragraphs of theText
set fixedText to ""
set {tids, text item delimiters} to {text item delimiters, tab}
repeat with i from 1 to count of listText
set listItems to {}
set thisList to text items of (item i of listText)
repeat with j from 1 to count of thisList
set thisItem to item j of thisList
if text -1 of thisItem is "-" then
set thisItem to "-" & text 1 thru -2 of thisItem
end if
set end of listItems to thisItem
end repeat
set fixedText to fixedText & (listItems as text) & character id 10
end repeat
set text item delimiters to tids
return text 1 thru -2 of fixedText
end fixNegativeSigns
NOTE: when testing my code above you should copy/paste it into Applescript Editor. You will have to fix the tab characters in originalText because they do not survive the copy/paste. So remove the spaces between the words/columns and insert a tab. Then the code will work correctly.

Resources