Applescript- For every item that grep finds - applescript

This code obviously won't work but I'm looking for a syntax change to make it work.
for every item that grep finds
set myCommand to do shell script "grep -w word test.log"
set mySecondCommand to do shell script "grep -w end test.log"
end
The following output should be correct (What I want):
word
end
word
end
instead I get because I do not have this theoretical "for every item that grep finds" statement (I don't want this output):
word
word
end
end

Your initial grep results will be in string format eg. one long string. In order to iterate them you will need to turn the string into a list, thus I use the "paragraphs" command. Once you have the initial grep results in list format, then you can use a repeat loop to process the items in the list. When you process the items you will need to store those results in a new list so that at the end of the script you can view the results in total. Something like this...
set firstWord to "word"
set secondWord to "end"
-- use the ls command and grep to find all the txt documents in your documents folder
set aFolder to (path to documents folder) as text
set grepResults to do shell script "ls " & quoted form of POSIX path of aFolder & " | grep \"txt\""
set grepResultsList to paragraphs of grepResults
-- search the found txt documents for the words
set totalResults to {}
repeat with aResult in grepResultsList
set thisPath to aFolder & aResult
try
set myCommand to paragraphs of (do shell script "grep -w " & firstWord & space & quoted form of POSIX path of thisPath)
set myCommandCount to count of myCommand
set end of totalResults to {thisPath, firstWord, myCommandCount, myCommand}
end try
try
set mySecondCommand to paragraphs of (do shell script "grep -w " & secondWord & space & quoted form of POSIX path of thisPath)
set mySecondCommandCount to count of mySecondCommand
set end of totalResults to {thisPath, secondWord, mySecondCommandCount, mySecondCommand}
end try
end repeat
return totalResults

Related

Get path to main iTunes library and play a song from it

I currently have an Applescript that lets you type in a song and play it.
Here it is:
set userInput to text returned of (display dialog "Type something" default answer "")
if userInput contains "Play " then
set {TID, text item delimiters} to {text item delimiters, {"Play "}}
if length of userInput is greater than or equal to 2 then set resultString to text item 2 of userInput
set text item delimiters to TID
set playSong to (resultString as string)
tell application "iTunes"
set mySongs to every track of library playlist 1 whose name is playSong
repeat with aSong in mySongs
play aSong
end repeat
if (count of mySongs) = 0 then
say "Song not found"
end if
end tell
end if
Basically, I need to get the path to the main iTunes library and play a song from it. Currently, to search for songs, iTunes has to open. And if it can't find the song, it just stays open. I want to search the actual iTunes directory to make it so if iTunes cannot find a song, it doesn't open
I have no idea how to do this.
Thanks
Here is the script to search in the "iTunes Library.xml" file.
set XMLFile to my get_iTunes_Library_xml()
set userInput to text returned of (display dialog "Type something" default answer "Play ")
if userInput begins with "Play " and length of userInput > 5 then
set playSong to text 6 thru -1 of userInput
set searchString to "<key>Name<\\/key><string>" & playSong & "<\\/string>" -- to match exact name
if (my searchTrackName(searchString, XMLFile)) is not "" then
tell application "iTunes" to play (tracks whose name is playSong)
else
say "Song not found"
end if
end if
on searchTrackName(t, f) -- search in iTunes Library.xml file
if "&" is in t then set t to do shell script "sed \"s/&/&/g\" <<<" & quoted form of t -- to replace "&" by "&"
try -- return a count of matching lines
return do shell script "grep -c -m1 -i " & (quoted form of t) & " " & f -- "-i" equal case insensitive, "-m 1" to exit at first match
end try
return ""
end searchTrackName
on get_iTunes_Library_xml() -- get the path
do shell script "defaults read com.apple.iApps iTunesRecentDatabases | sed -En 's:^ *\"(.*)\"$:\\1:p' |/usr/bin/perl -MURI -e 'print URI->new(<>)->file;'"
return quoted form of the result
end get_iTunes_Library_xml
The "com.apple.iApps.plist" file contains the path to yours iTunes libraries (if you have more than one), the script get the path of the "iTunes Library.xml" file of the current library.
Not a finished solution, but perhaps a starting point.
I didn't find a way to get automatically the path to the iTunes library.
With the StandardAdditions you can get the path to the main music folder in the home folder via
set searchPath to POSIX path of music folder
You can set the path manual, like this:
set searchPath to quoted form of "/Users/USERNAME/Music/iTunes/iTunes Music/"
To search for the music files without iTunes, i use the shell command "mdfind"
do shell script "mdfind -count -onlyin PATH SEARCHSTRING"
With the count-Flag we get the total numbers of matches. If you like to see what mdfind finds, omit the count-Flag.
tell application "System Events"
set userInput to text returned of (display dialog "Search for music" default answer "madonna")
set searchPath to POSIX path of music folder
end tell
set shellCommand to "mdfind -count -onlyin " & searchPath & " " & quoted form of userInput
set searchResult to (do shell script shellCommand) as number
if searchResult = 0 then
say "Song not found"
else if searchResult >= 1 then
say "Found some songs"
end if
With mdfind you can search in the metadata, for example you can search for only MP3-Files:
mdfind "kMDItemContentType=='public.mp3'"

Applescript: Break a set of lines into blocks based on a condition

I have an Automator service for uploading images and returning URLs to a text editor.
It works very well, but there's something I want to improve:
When the workflow starts, Automator will get all images in a folder and upload them to an FTP server.
Then it returns a result like below:
("http://url/0530/pic01/pic-01.jpg",
"http://url/0530/pic01/pic-02.jpg",
"http://url/0530/pic01/pic-03.jpg",
"http://url/0530/pic01/pic-04.jpg",
"http://url/0530/pic02/pic-01.jpg",
"http://url/0530/pic02/pic-02.jpg",
"http://url/0530/pic02/pic-03.jpg",
"http://url/0530/pic02/pic-04.jpg",
"http://url/0530/pic03/pic-01.jpg",
"http://url/0530/pic03/pic-02.jpg",
"http://url/0530/pic03/pic-03.jpg",
"http://url/0530/pic03/pic-04.jpg")
And the workflow gets these strings and puts them in a new text document.
Finally, here is the result in a text editor:
http://url/0530/pic01/pic-01.jpg
http://url/0530/pic01/pic-02.jpg
http://url/0530/pic01/pic-03.jpg
http://url/0530/pic01/pic-04.jpg
http://url/0530/pic02/pic-01.jpg
http://url/0530/pic02/pic-02.jpg
http://url/0530/pic02/pic-03.jpg
http://url/0530/pic02/pic-04.jpg
http://url/0530/pic03/pic-01.jpg
http://url/0530/pic03/pic-02.jpg
http://url/0530/pic03/pic-03.jpg
http://url/0530/pic03/pic-04.jpg
But I want it to be:
http://url/0530/pic01/pic-01.jpg
http://url/0530/pic01/pic-02.jpg
http://url/0530/pic01/pic-03.jpg
http://url/0530/pic01/pic-04.jpg
http://url/0530/pic02/pic-01.jpg
http://url/0530/pic02/pic-02.jpg
http://url/0530/pic02/pic-03.jpg
http://url/0530/pic02/pic-04.jpg
http://url/0530/pic03/pic-01.jpg
http://url/0530/pic03/pic-02.jpg
http://url/0530/pic03/pic-03.jpg
http://url/0530/pic03/pic-04.jpg
I think I can use AppleScript in Automator to do this before the result is sent to the text editor.
Do you have any coding advice?
===================================================
Thanks # user309603 and # mklement0 so much!!
I choose pure applescript method.
Here is my code in automator that run applescript in workflow:
on run {input, list}
set txtG to first item of input
repeat with txtLine in items 2 thru -1 of input
if txtLine contains "-01" then set txtG to txtG & linefeed
set txtG to txtG & linefeed & txtLine
end repeat
return txtG
end run
Here is a pure applescript solution.
I would prefer mklement0's awk-solution. It is much faster if you have long URL-lists.
set txt to "http://url/0530/pic01/pic-01.jpg
http://url/0530/pic01/pic-02.jpg
http://url/0530/pic01/pic-03.jpg
http://url/0530/pic02/pic-01.jpg
http://url/0530/pic03/pic-01.jpg
http://url/0530/pic03/pic-02.jpg
http://url/0530/pic03/pic-03.jpg
http://url/0530/pic03/pic-04.jpg
http://url/0530/pic04/pic-01.jpg"
set txtG to first paragraph of txt
repeat with txtLine in paragraphs 2 thru -1 of txt
if txtLine contains "-01" then set txtG to txtG & linefeed
set txtG to txtG & linefeed & txtLine
end repeat
return txtG
The following AppleScript snippet demonstrates the approach you can use in principle - I'm unclear on the exact circumstances:
If you must process the raw result:
# Sample input text.
set txt to "(\"http://url/0530/pic01/pic-01.jpg\",
\"http://url/0530/pic01/pic-02.jpg\",
\"http://url/0530/pic01/pic-03.jpg\",
\"http://url/0530/pic01/pic-04.jpg\",
\"http://url/0530/pic02/pic-01.jpg\",
\"http://url/0530/pic02/pic-02.jpg\",
\"http://url/0530/pic02/pic-03.jpg\",
\"http://url/0530/pic02/pic-04.jpg\",
\"http://url/0530/pic03/pic-01.jpg\",
\"http://url/0530/pic03/pic-02.jpg\",
\"http://url/0530/pic03/pic-03.jpg\",
\"http://url/0530/pic03/pic-04.jpg\")"
# Group (break into blocks) by files containing "-01."
set txtGrouped to do shell script ¬
"printf %s " & quoted form of txt & " | tr -d '()\"'" & ¬
" | awk -F, 'NR>1 && /-01\\./ { print \"\" } { print $1 }'" ¬
without altering line endings
If you already have a cleaned-up set of URL-only lines:
# Sample input text.
set txt to "http://url/0530/pic01/pic-01.jpg
http://url/0530/pic01/pic-02.jpg
http://url/0530/pic01/pic-03.jpg
http://url/0530/pic01/pic-04.jpg
http://url/0530/pic02/pic-01.jpg
http://url/0530/pic02/pic-02.jpg
http://url/0530/pic02/pic-03.jpg
http://url/0530/pic02/pic-04.jpg
http://url/0530/pic03/pic-01.jpg
http://url/0530/pic03/pic-02.jpg
http://url/0530/pic03/pic-03.jpg
http://url/0530/pic03/pic-04.jpg"
# Group (break into blocks) by files containing "-01."
set txtGrouped to do shell script ¬
"printf %s " & quoted form of txt & ¬
" | awk 'NR>1 && /-01\\./ { print \"\" } { print }'" ¬
without altering line endings
Uses do shell script to have awk perform the desired grouping.
Note:
without altering line endings is required to prevent AppleScript from replacing \n chars in the output with Mac-style \r line endings.
The result will have a trailing \n char, even if the input didn't. To fix this, use:
set txtGrouped to text 1 thru ((length of txtGrouped) - 1) of txtGrouped
If the goal is to always divide the list items into paragraphs grouped by four, here is an applescript you can put in an automator action:
set l to input as list
set r to ""
repeat with n from 1 to (count l) by 4
set r to r & item n of l & return & item (n + 1) of l & return & item (n + 2) of l & return & item (n + 3) of l & return & return
end repeat
return r
Clarify if instead what you need is to group all the versions of one pic together, but it won't always be 4 each, and that the script needs to check the file names to determine.
Here is a solution : This script checks the name of the parent folder for each file, when the folder name is not the same, it add a blank line.
Append the Run Shell Script action into your workflow, select the "/bin/bash" shell and select "to stdin"
Put this script in the Run Shell Script action :
awk -F/ '{f=$(NF - 1); if (NR==1) {fName=f} else if (f != fName) {print ""; fName=f} print}' < "/dev/stdin"

Applescript Duplicate Word Count

How might I create an applescript that would count duplicate words in a pdf, and then display the results in a hierarchy with the most duplicated word at the top (with its count) and the second most second, so on and so forth? I'd like to use this in school, so that after converting ppt's to pdf I can run this script to see what is most important in the presentation.
Ideally it would filter out words such as: the, so, it, etc.
The last part you are looking for is simple.
Just set up a list and check if the word is in it or not.
set ignoreList to {"to", "is"}
set reportFile to "/Users/USERNAME/Desktop/Word Frequencies.txt"
set theTextFile to "Users/USERNAME/Desktop/foo.txt")
set word_list to every word of (do shell script "cat " & quoted form of theTextFile)
set word_frequency_list to {}
repeat with the_word_ref in word_list
set the_current_word to contents of the_word_ref
if the_current_word is not in ignoreList then
set word_info to missing value
repeat with record_ref in word_frequency_list
if the_word of record_ref = the_current_word then
set word_info to contents of record_ref
exit repeat
end if
end repeat
if word_info = missing value then
set word_info to {the_word:the_current_word, the_count:1}
set end of word_frequency_list to word_info
else
set the_count of word_info to (the_count of word_info) + 1
end if
end if
end repeat
--return word_frequency_list
set the_report_list to {}
repeat with word_info in word_frequency_list
set end of the_report_list to quote & the_word of word_info & ¬
quote & " - appears " & the_count of word_info & " times."
end repeat
set AppleScript's text item delimiters to return
set the_report to the_report_list as text
do shell script "echo " & quoted form of the_report & " > " & quoted form of reportFile
set AppleScript's text item delimiters to ""
delay 1
do shell script " open " & quoted form of reportFile
I have also changed some of the code to use shell script to read/write the file. Only because I prefer using it rather than Textedit.
While it is doable in applescript, as shown by markhunte, it is VERY slow. If you are processing larger pieces of text or lots of files, applescript is extremely slow. In my tests I gave up on it. So, here is a short shell script, which you can call from applescript if you need to, that is very fast.
#!/bin/sh
[ "$1" = "" ] || [ "$2" = "" ] && echo "$0 [wordsfile] [textfile]" && exit 1
INFILE="$2"
WORDS="${2}.words"
EXWORDS="$1"
echo "File $INFILE has `cat $INFILE | wc -w ` words."
echo "Excluding the `cat $EXWORDS | wc -w` words."
echo "Extracting words from file and removing common words..."
grep -o -E '\w{3,}' $INFILE | grep -x -i -v -f $EXWORDS > $WORDS
echo "Top 10 most frequest words in $INFILE are..."
cat "$WORDS" | tr [:upper:] [:lower:] | sort | uniq -c | sort -rn | head -10
# Clean up
rm $WORDS

Get part of string in Applescript

I try to make a applescript that read files in a folder and takes only part of the filename. The files would look like this: the.name.of.a.tv.show.s01e01
I could search for s01 but then i have to make a rule for every season that can come.
Is there some way to look for s--e-- and then take the part of the filename before that?
Try:
set xxx to "the.name.of.a.tv.show.s01e01 etc etc"
set yyy to (do shell script "echo " & xxx & " | sed 's/.s[0-9][0-9]e[0-9][0-9].*//'")
return yyy
Incorporating your previous question:
set seasonList to {}
repeat with aShow in listOfShows
set aShow to aShow as string
set end of seasonList to (do shell script "echo " & aShow & " | sed 's/.s[0-9][0-9]e[0-9][0-9].*//'")
end repeat
return seasonList

Read folder, parse filenames and call other program

In brief, I need to do something like this:
I have a folder with a lot of files and want to process all files with extension .epub.
All files already follow a naming scheme: Lastname, Firstname - Title.epub or Lastname, Firstname - Series x - Title.epub and I need a parser for Lastname, Firstname, Series (if existing) and Title.
I have a command-line tool that sets metadata: ebook-meta filename -a "Firstname Lastname" -t Title
There are many snipplets for 1.), however I am in need for input for 2.) and appreciate any help/pointers!
You can start with the following and change it to meet your needs. It compiles, although untested.
set p to POSIX file "/Users/kaass/Desktop/test/"
tell application "Finder" to set filelist to name of every file of folder p
repeat with filename in filelist
set text item delimiters to ""
if text -5 thru -1 of filename is equal to ".epub" then
set temp to items 1 thru -6 of filename as text
set text item delimiters to " - "
set myWord to text items 1 thru -1 of temp
set title to myWord's last item as text
if myWord's length is equal to 3 then set series to myWord's second item as text
set myWord to item 1 of myWord as text
if myWord contains "," then
set text item delimiters to ", "
else
set text item delimiters to " "
end if
set author to (text item 2 of myWord) & space & (text item 1 of myWord)
set path_and_filename to POSIX path of file p & filename
do shell script "echo Processing file " & quoted form of path_and_filename & ": " & author & " +++ " & title
do shell script "/Applications/calibre.app/Contents/MacOS/ebook-meta " & quoted form of path_and_filename & " -a " & quoted form of author & " -t " & quoted form of title
end if
end repeat
Just comment if you need something to be changed.

Resources