This script is what I made/hacked together thanks to this great communiy and its members.
what it’s need to do is this
user enters a search string
script will search all text files in a certain folder
copy all lines from those text files in a new text file and save it on desktop
on run
-- create empty txt file on desktop
set thedate to (do shell script "/bin/date +%y%m%d_%H%M%S_")
set filename to thedate & "test.txt"
tell application "Finder" to make new file at desktop with properties {name:filename}
-- enter search criteria
set search_criteria to text returned of (display dialog "enter search string" default answer "")
-- look in these files. need to change this to desktop folder which wil hold multiple files
set theFolder to ((path to desktop as text) & "LOGS:")
tell application "Finder" to set theFiles to files of folder theFolder
repeat with oneFile in theFiles
set somePOSIXFile to oneFile as alias
set somePOSIXFile to (POSIX path of (somePOSIXFile))
-- read lines of file
set myfilepath to POSIX file somePOSIXFile as string
set thedata to paragraphs of (read file myfilepath)
-- search in file(s) if string is found
set searchResult to (do shell script "/usr/bin/grep -q" & space & quoted form of search_criteria & space & quoted form of somePOSIXFile & space & "; echo $?")
display dialog searchResult as text
--test
-- if found
if searchResult = "0" then
-- fill text file on desktop with lines with search criteria
repeat with i in thedata
if i contains search_criteria then
set thePath to (path to desktop as Unicode text) & filename
set fileRef to open for access alias thePath with write permission
write i & (ASCII character 13) to fileRef starting at eof
close access fileRef
set searchResult to "0"
end if
end repeat
-- if not ** need to change this so that this runs only one time ** is now running as much as there are files in the log folder
else if searchResult = "1" then
try
tell application "Finder"
set the file_to_delete to (path to desktop) & filename as string
delete alias file_to_delete
end tell
end try
end if
end repeat
end run
however
after running the script I can’t save it anymore
if i make it an script app it also gives me a safe error even after the whole copy part
the part where it delets a file from the desktop runs as much as there are files in the log folder. i know that;s because of the repeat with oneFile in theFiles part but I need it to run only once
if the script finds the string in all or the last text files it works fine but it deletes the txt file from the dektop if it doesn’t find it in the last txt file
That’s probably because all your variables are “run handler” variables, whose values, like those of properties and globals, are saved back into the script file after it’s run. If your last text is very long, the list of its paragraphs will be too bulky to be saved back into the file with your variable ‘thedata’ and you’ll get an error. The cure is either to set thedata to something brief (perhaps “”) before the script exits or, better still, to declare thedata as local. Even better still, make all the variables local by putting the code in an ordinary handler.
These two are the same phenomenon, of course. To delete the file only under the right circumstances, you’d have to do it after the repeat, depending on the value of some flag variable:
set noMatches to true -- Set this variable to a default value of 'true'.
repeat with oneFile in theFiles
-- .
if searchResult = "0" then
-- Write to the file.
set noMatches to false -- Change the flag to 'false'.
end if
end repeat
if (noMatches) then
-- Delete the file.
end if
But in fact you don’t need to create the file in the first place if there are no matches. The ‘open for access’ command will create it if it doesn’t exist, so there’s no need to have the Finder do it beforehand.
There are more efficient ways to write your script, but this should help with the immediate problems.
Further to the above, here’s one way the script might be written.
on mainHandler()
-- Set name for txt file on desktop
set thedate to (do shell script "/bin/date +%y%m%d_%H%M%S_")
set filename to thedate & "test.txt"
set thePath to (path to desktop as Unicode text) & filename
-- enter search criteria
set search_criteria to text returned of (display dialog "enter search string" default answer "")
-- Get the log files as aliases.
set theFolder to ((path to desktop as text) & "LOGS:")
tell application "Finder"
try
set theFiles to (files of folder theFolder) as alias list
on error
set theFiles to (first file of folder theFolder) as alias as list
end try
end tell
-- Create the file to which to write the matched text and open it for access.
set fileRef to open for access file thePath with write permission
try -- In case there's an error while the file's open.
-- Check each log file in turn.
repeat with oneFile in theFiles
set oneFilePOSIX to (POSIX path of oneFile)
-- search in file(s) if string is found
try -- In case there's no match in this file.
set matchedText to (do shell script "/usr/bin/grep" & space & quoted form of search_criteria & space & quoted form of oneFilePOSIX)
set textMatched to true
on error number 1
set textMatched to false
end try
if (textMatched) then write matchedText & return to fileRef starting at eof
end repeat
on error errMsg
display dialog errMsg buttons {"OK"} default button 1 with icon stop
end try
set noMatches to ((get eof fileRef) = 0) -- Has anything been written to the result file?
close access fileRef
if (noMatches) then tell application "Finder" to delete file thePath
end mainHandler
mainHandler()
I was still digesting your first post and then I received notification about the 2nd. wow. so fast also. need to go over it line by line and learn from your script.
Noticed that it doesn’t copy only the lines with the search string but everything from the file that the search string is found in.
Will get back to you after detail testing but… WOW!
The idea was that the “grep” command returns text containg only the paragraphs with the matching text. However, the file I was using has linefeeds rather than returns. I suppose the script may not work if it’s the other way round. Apologies if that’s the case. I’ll take another look later on.
OK. This should work with plain text containing either linefeeds and/or returns, the output being plain text with returns.
on mainHandler()
-- Set name for txt file on desktop
set thedate to (do shell script "/bin/date +%y%m%d_%H%M%S_")
set filename to thedate & "test.txt"
set thePath to (path to desktop as Unicode text) & filename
-- enter search criteria
set search_criteria to text returned of (display dialog "enter search string" default answer "")
-- Get the log files as aliases.
set theFolder to ((path to desktop as text) & "LOGS:")
tell application "Finder"
try
set theFiles to (files of folder theFolder) as alias list
on error
set theFiles to (first file of folder theFolder) as alias as list
end try
end tell
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
-- Create the file to which to write the matched text and open it for access.
set fileRef to open for access file thePath with write permission
try -- In case there's an error while the file's open.
-- Check each log file in turn.
repeat with oneFile in theFiles
set txt to (read oneFile)
if (txt contains search_criteria) then
set txt to txt's paragraphs
set matchedText to {}
repeat with i from 1 to (count txt)
set thisPara to item i of txt
if (thisPara contains search_criteria) then set end of matchedText to thisPara
end repeat
write ((matchedText as text) & return) as text to fileRef starting at eof
end if
end repeat
on error errMsg
display dialog errMsg buttons {"OK"} default button 1 with icon stop
end try
set noMatches to ((get eof fileRef) = 0) -- Has anything been written to the result file?
close access fileRef
set AppleScript's text item delimiters to astid
if (noMatches) then tell application "Finder" to delete file thePath
end mainHandler
mainHandler()