I wrote an AppleScript that returns a random string from a text file delineated by commas:
set some_file to "Macintosh HD:Users:Zade:Library:Application Support:Notational Data:Words.txt" as alias
set the_text to read some_file as string
set the text item delimiters of AppleScript to ", "
set the_lines to (every text item of the_text)
return some item of the_lines
But I now have a text file delineated by new lines instead of commas. And each line begins with anywhere from 0-20 spaces. I want to return just the text portion of a random line. How do I do this?
Also, if the text portion is surrounded by plain (not curly) quotes, how can I trim the quotes?
The following script will handle the additional requirements from your comments, and includes statements to trim characters from the beginning and ending of the string. It excludes the first 27 lines read from the file and will repeatedly get and trim random lines from the list until the final result is not empty.
set theFile to (choose file)
set theLines to paragraphs 28 thru -1 of (read theFile)
repeat -- forever
set someLine to some item of theLines
-- trim characters at the start
if someLine is not "" then repeat until the first character of someLine is not in {space, tab, quote}
if (count someLine) is 1 then
set someLine to ""
exit repeat
end if
set someLine to text 2 thru -1 of someLine
end repeat
-- trim characters at the end
if someLine is not "" then repeat until the last character of someLine is not in {quote}
if (count someLine) is 1 then
set someLine to ""
exit repeat
end if
set someLine to text 1 thru -2 of someLine
end repeat
if someLine is not "" then exit repeat
end repeat
return someLine
Here is what I use to trim spaces from both ends of a string
on trimWhiteSpace(aString)
if aString is not "" then
-- setup for no delimiter
set savedTextItemDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ""
-- start with the tail end by revering the list
set these_items to reverse of (every text item of aString)
-- keep peeling off 1st space
repeat while item 1 of these_items is space
set these_items to rest of these_items
end repeat
-- flip the list, now do the leading characters
set these_items to reverse of these_items
repeat while item 1 of these_items is space
set these_items to rest of these_items
end repeat
-- reconstruct the string
set these_items to these_items as string
-- restore and return
set AppleScript's text item delimiters to savedTextItemDelimiters
return these_items
end if
end trimWhiteSpace
Change the comma and space in the line set the text item delimiters of AppleScript to ", " to return. The new line (no pun intended) looks like this:
set the text item delimiters of AppleScript to return
As for your second question try this:
set AppleScript's text item delimiters to ""
return text items 2 thru -2 of some_string
Let's put it all together!
set some_file to "Macintosh HD:Users:Zade:Library:Application Support:Notational Data:Words.txt" as alias
set the_text to read some_file as string
set the_lines to (every paragraph of the_text)
set this_line to some item of the_lines
if this_line is not "" then
set AppleScript's text item delimiters to ""
set this_line to (text items 2 thru -2 of this_line) --remove the quotes
set AppleScript's text item delimiters to space
set these_items to (every text item of this_code)
set the this_line to (item 1 of these_items & this_line)
set AppleScript's text item delimiters to ""
return this_line
end if
EDIT: You can't stop the program from returning empty lines, but you can filter them out like so...
if paragraph i of some_text is not "" then do_something()
Related
So I have a string but I only want it after a certain part. I know that you would optimally do this in shell so I tried, but my limited shell knowledge didn't bring me far. This post tries to do a similar thing but not exactly what I need.
set theString to "hello/world"
do shell script "echo " & theString & "???"
return theString --the output should be hello
There's no shell script needed. Get the position of the slash in the string and return the substring from the beginning to the position - 1
set theString to "hello/world"
set slashIndex to offset of "/" in theString
return text 1 thru (slashIndex - 1) of theString
You can also use AppleScript's text item delimiters:
set theString to "hello/world"
set {TID, AppleScript's text item delimiters} to ¬
{AppleScript's text item delimiters, "/"}
set theString to first text item of theString
set AppleScript's text item delimiters to TID
do shell script "echo " & theString's quoted form & "???"
Returns:
hello???
However, return theString after processing with AppleScript's text item delimiters will just return hello in this use case.
Note the use of 's quoted form in theString's quoted form with the variable in the do shell script command, as you should always quote what's being passed to the shell. You can also use this form: quoted form of theString
As you can see the offset of method presented in one of the other answers is more straight forward, however I've added this as an answer so you know what your other options are.
This also works.
set theString to "hello/world"
set firstWord to 1st word of theString
return firstWord
OR
If there are any other characters and including “/“ in theString , the following should take care of that.
set theString to "hello/world"
set firstWord to 1st word of (do shell script "echo " & ¬
quoted form of theString & " | sed -E 's#[^[:alpha:]]{1,}# #'")
return firstWord
Essentially i'm looking for an applescript that allow me to order the massive 50.000 files by creating folders that have just the first word of the files, ignoring the rest of the filename after the first space.
For eaxmple the 50.000 files are named like this:
- amazingfrog -shootingbase.jpg
- frog 2sHDn1_9fFs12s.jpg
- frog 29adjjdd39939.mov
- Horse IUS39aosdja.mov
- horse 282131888.jpg
- HORSE.jpg
And so on.....
- I would like to be like this:
- amazingfrog
-amazingfrog -shootingbase.jpg
- frog
-frog 2sHDn1_9fFs12s.jpg
-frog 29adjjdd39939.mov
- horse
-horse IUS39aosdja.mov
-horse 282131888.jpg
-horse.gif
And so on....
On the internet i came across with the following script:
set chosenFolder to (choose folder)
tell application "Finder" to set fileList to files of chosenFolder
repeat with aFile in fileList
set {name:Nm, name extension:Ex} to info for (aFile as alias)
if Ex is missing value then set Ex to ""
if Ex is not "" then set Nm to text 1 thru ((count Nm) - (count Ex) - 1) of Nm
set dateFolder to text 1 thru 15 of Nm
set sourceFile to quoted form of POSIX path of (aFile as text)
set destinationFile to quoted form of (POSIX path of chosenFolder & dateFolder & "/" & name of aFile)
do shell script "ditto " & sourceFile & space & destinationFile
do shell script "rm " & sourceFile
end repeat
The only problem is that i have to choose in the "text 1 thru" the numbers of the letters i want to keep. And unfortunately the first word of the filenames have different length...
Could be possible to modify this script to my needed? or do you have any other suggestions?
Thanks in advance for any reply!!
I recommend to use text item delimiters to extract the first part of the file name
set chosenFolder to (choose folder)
tell application "Finder" to set fileList to files of chosenFolder
set TID to text item delimiters
set text item delimiters to space
repeat with aFile in fileList
set fileName to name of aFile
set textItems to text items of fileName
if (count textItems) = 1 then
set fileExtension to name extension of aFile
set folderName to text 1 thru ((get offset of "." & fileExtension in fileName) - 1) of fileName
else
set folderName to first item of textItems
end if
set sourceFile to quoted form of POSIX path of (aFile as text)
set destinationFile to quoted form of (POSIX path of chosenFolder & folderName & "/" & fileName)
do shell script "ditto " & sourceFile & space & destinationFile
do shell script "rm " & sourceFile
end repeat
set text item delimiters to TID
I've got the following shell script which uses osascript command:
#!/usr/bin/osascript
on run argv
tell application "Terminal"
activate
do script "echo " & quoted form of (item 1 of argv) & " " & quoted form of (item 2 of argv)
end tell
end run
However when I run, the code is only limited to print 2 first arguments.
E.g. when running ./test.sh foo bar buzz ..., I expect all the arguments to be displayed.
How I can convert the above code to support multiple unlimited number of arguments? And it won't break when I specify none?
By default, AppleScript's text item delimiters is {} and unless is was set to other then the default elsewhere in the script before this and not reset as one should directly after the manipulation, and or you just are not using AppleScripts's text item delimiters, then here is a way to do it without having to explicitly use code like e.g. set {TID, text item delimiters} to {text item delimiters, space} and set text item delimiters to TID:
#!/usr/bin/osascript
on run argv
set argList to {}
repeat with arg in argv
set end of argList to quoted form of arg & space
end repeat
tell application "Terminal"
activate
do script "echo " & argList as string
end tell
end run
You have to add a repeat loop to map the argument list to their quoted form and then join the list to a space separated string with text item delimiters
#!/usr/bin/osascript
on run argv
set argList to {}
repeat with arg in argv
set end of argList to quoted form of arg
end repeat
set {TID, text item delimiters} to {text item delimiters, space}
set argList to argList as text
set text item delimiters to TID
tell application "Terminal"
activate
do script "echo " & argList
end tell
end run
I have multiple folders with sub folders that have files in them that need to be labeled with their parent folder+grandparent folder name.
i.e. Folder 1>Folder 2>File.jpg needs to be renamed to Folder_1_Folder_2_File.jpg
I was able to find a script that somewhat does it, and have been trying to reverse engineer it, but am not having any luck. The script below presents two challenges, 1) It includes the entire path from the root directory, and two, it deletes the name of the file, therefore only allowing one file to be renamed before it errors out. I know that the problem is that the script is renaming the entire file, I just don't know how to proceed.
tell application "Finder"
set a to every folder of (choose folder)
repeat with aa in a
set Base_Name to my MakeBase(aa as string)
set all_files to (every file in aa)
repeat with ff in all_files
set ff's name to (Base_Name & "." & (ff's name extension))
end repeat
end repeat
end tell
to MakeBase(txt)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ":"
set new_Name_Raw to every text item of txt
set AppleScript's text item delimiters to "_"
set final_Name to every text item of new_Name_Raw as text
set AppleScript's text item delimiters to astid
return final_Name
end MakeBase
Thank you!
tell application "Finder"
repeat with theItem in (the selection as list)
set theItem's name to (theItem's container's container's name) & "_" & (theItem's container's name) & "_" & (theItem's name)
end repeat
end tell
If you want to learn how AppleScript can work with an app, look through the app's dictionary of AppleScript commands (AppleScript Editor > File > Open Dictionary...).
Edit 1
Here's a version in which you select the "grandparent folder" containing folders containing the items to rename:
tell application "Finder"
set itemsToRename to {}
set selectedFolders to (the selection as list)
repeat with selectedFolder in selectedFolders
set childFolders to every item of selectedFolder
repeat with childFolder in childFolders
set grandchildItems to every item of childFolder
set itemsToRename to itemsToRename & grandchildItems
end repeat
end repeat
repeat with theItem in itemsToRename
set theItem's name to (theItem's container's container's name) & "_" & (theItem's container's name) & "_" & (theItem's name)
end repeat
end tell
Try:
set myFolder to do shell script "sed 's/\\/$//' <<< " & quoted form of POSIX path of (choose folder)
set myFiles to paragraphs of (do shell script "find " & quoted form of myFolder & " \\! -name \".*\" -type f -maxdepth 2 -mindepth 2")
repeat with aFile in myFiles
tell application "System Events" to set file aFile's name to (do shell script "sed 's/.*\\/\\([^/]*\\)\\/\\([^/]*\\)\\/\\([^/]*$\\)/\\1_\\2_\\3/' <<< " & quoted form of aFile)
end repeat
The script below basically you choose a folder with PDFs, get file count of PDFs on chosen folders, write the results in text file, open the text file in Excel. The scripts works fine but I get entire the file path.
Results are:
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/BODY/: 65
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/BODY/: RESENDS 0
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/COVERS/: 23
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/COVERS/: RESENDS 6
I want to strip everything before the bullet • then for every / a column. Something like this:
CUSTO_4 BODY 65
CUSTO_4 BODY RESENDS 0
CUSTO_4 COVERS 23
CUSTO_4 COVERS RESENDS 6
I trying to grasp the concept of text item delimiters and using the offset command but I don't know how to implement that into the script.
set target_folder to choose folder with prompt "Choose target folders containing only PDFs to count files" with multiple selections allowed without invisible
set results to ""
repeat with i from 1 to (count target_folder)
set thisFolder to (POSIX path of item i of target_folder)
--Find & count all PDFs in folders selected that DON'T starts with letter R
set fileCount to do shell script "find " & quoted form of thisFolder & " -type f -name *.pdf -and -not -iname 'R[0-9-_]*.pdf' | wc -l"
set results to (results & "" & thisFolder & ":" & fileCount & return)
--Find & count all PDFs in folders selected that starts with letter R
set fileCount to do shell script "find " & quoted form of thisFolder & " -type f -iname 'R[0-9-_]*.pdf' | wc -l"
set results to (results & "" & thisFolder & ":" & tab & tab & "RESENDS" & fileCount & return)
end repeat
--write results to a txt file
set theFilePath to (path to desktop folder as string) & "PDF File Count.txt"
set theFile to open for access file theFilePath with write permission
try
set eof of theFile to 0
write results to file theFilePath
close access theFile
on error
close access theFile
end try
--Will open the the PDF File Count.txt in Excel
tell application "Microsoft Excel"
activate
open text file filename "PDF File Count.txt"
end tell
AppleScript's text item delimiters are used to determine how text is broken apart and/or reassembled. When you get the text items of a string, the string is broken apart at each delimiter, and the result is a list of the pieces. Going the other way, if you coerce a list of text items to a string, the pieces are reassembled with the delimiter used in between each piece.
For your example, you could use something like the following (I added a little formatting to get your result):
set theList to {¬
"/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/BODY/: 65", ¬
"/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/BODY/: RESENDS 0", ¬
"/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/COVERS/: 23", ¬
"/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/COVERS/: RESENDS 6"}
set finalResult to {} -- this will be the final result
set tempTID to AppleScript's text item delimiters -- stash the original delimiters
repeat with anItem in theList
set AppleScript's text item delimiters to "•"
set pieces to text items of anItem -- break apart at bullets
log result
set theFile to (rest of pieces) as text -- drop the first piece and reassemble
set AppleScript's text item delimiters to "/"
set pieces to text items of theFile -- now break apart at slashes
log result
set lastPiece to last item of pieces -- trim the last piece a bit
set theCount to 0
repeat while first character of lastPiece is in {space, ":"}
set lastPiece to text 2 thru -1 of lastPiece -- trim it
set theCount to theCount + 1 -- count up trimmed characters
end repeat
if theCount > 4 then set lastPiece to tab & tab & lastPiece -- add a little formatting...
set last item of pieces to lastPiece -- put the trimmed piece back
set text item delimiters to tab & tab
set pieces to pieces as text -- put the pieces back together with tabs
log result
set end of finalResult to pieces -- store the reassembled text for later
end repeat
set AppleScript's text item delimiters to tempTID -- restore the original delimiters
choose from list finalResult with empty selection allowed -- show the results
You don't always have to use text item delimiters to manipulate text:
set xxx to "/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/BODY/: 65
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/BODY/: RESENDS 0
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/COVERS/: 23
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/COVERS/: RESENDS 6"
set yyy to do shell script "echo " & quoted form of xxx & " | grep -o •.* | sed -e 's/•\\(.*\\):\\(.*\\)/\\1\\2/' -e 's/\\// /'g"
and the other approach:
set xxx to "/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/BODY/: 65
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/BODY/: RESENDS 0
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/COVERS/: 23
/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•CUSTO_4/COVERS/: RESENDS 6"
-- break apart and capture original delimiters
set {Astid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "/Volumes/PREPRESS/1_CATALOG/2_Press/PRINT_Catalog/2012/•"}
set yyy to text items 2 thru -1 of xxx
--put together
set AppleScript's text item delimiters to {""}
set yyy to yyy as string
-- break apart
set AppleScript's text item delimiters to ":"
set yyy to text items of yyy
--put together
set AppleScript's text item delimiters to {""}
set yyy to yyy as string
-- break apart
set AppleScript's text item delimiters to "/"
set yyy to text items of yyy
--put together
set AppleScript's text item delimiters to tab
set yyy to yyy as string
-- reset original delimiters
set AppleScript's text item delimiters to Astid
return yyy