Hi, I want to edit many nfo files with TextWrangler.
Every nfo file is inside its folder.
My files are like these one:
Desired result:
I am very new to AppleScript. Searching the forum and looking for part of codes I could arrange the next script but nothing happens.
set theSourceFolder to (choose folder with prompt "Select a folder:")
-- Select only all the nfo files of all subfolders
tell application "Finder"
set filesArray to every file of theSourceFolder whose name extension is "nfo"
end tell
repeat with aFile in filesArray
tell application "TextWrangler"
open (aFile as alias)
tell document 1
-- Copy to the clipboard the matched lines and paste them into the document
process lines containing matching string "(<\\?xml|<movie>|</movie>|</id>|</title>|<actor>|</actor>|</name>|</genre>|</year>|</tag>|</set>|</plot>)" matching with grep true ¬
output options {copying to clipboard:true}
select text 1 of project window 1
paste
-- Replace the title with the id data and save the document as nfo file
replace "<title>([\\w\\W]+)\\s-\\s([\\w\\W]+)<\\/title>" using "<title>\\1<\\/title>" searching in text 1 options {search mode:grep, starting at top:true, match words:true}
save
end tell
end tell
-- Clear and empty contents in the clipboard
tell application "System Events"
try
set the clipboard to ""
on error err_message
display dialog err_message
end try
end tell
end repeat
Apreciate if someone could help me to find my errors and make the script work.
Thank you in advance,
Alejandro
Model: mac mini 2011
AppleScript: 2.6.1
Browser: Safari 537.36
Operating System: Mac OS X (10.9)
It’s not really necessary to use TextWrangler to edit the files, but to get your script working:
set theSourceFolder to (choose folder with prompt "Select a folder:")
-- Select only the nfo files of the folder.
tell application "Finder"
set filesArray to (every file of theSourceFolder whose name ends with ".nfo") as alias list -- The Finder doesn't recognise "nfo" as a file extension on my machine. :\
end tell
repeat with aFile in filesArray
tell application "TextWrangler"
set docName to name of (open aFile)
tell document docName
-- Set the document text to just the lines which need to be kept.
set its text to copied lines of (process lines containing matching string "(<\\?xml|<movie>|</movie>|</id>|</title>|<actor>|</actor>|</name>|</genre>|</year>|</tag>|</set>|</plot>)" with matching with grep)
-- Find the id text.
set idText to found text of (find "(?<=<id>)[^<]*+(?=</id>)" options {search mode:grep, starting at top:true})
-- Replace the title with the id text.
replace "(?<=<title>)[^<]*+(?=</title>)" using idText options {search mode:grep, starting at top:true}
close saving yes
end tell
end tell
end repeat
The script works but only for the first nfo file. Then I get the next error: “TextWrangler has detected an error: Cannot get the name of text document 1”
Also, when I run the script in my “Films” folder nothing happens.
My folder structure is like this:
You said that is not necessary TextWrangler to edit the files. Is there any other way?
I was trying to add this extra line “FAVORITES” before the last line of my edited files.
I don`t have any idea how to make it. Sorry for not mention it before.
Thank you for any help. I will still crashing my head how to solve this.
Ah. I suspect this is due to the potential problem I was actually trying to avoid by getting the document’s name! It worked well with a folder-full of files on my computer, but obviously the timing’s different on yours.
In the script you posted, there’s a contraction between the comment (‘files of all subfolders’) and the code (‘every file of theSourceFolder’). I made the wrong guess about which was intended.
Here’s another version which hopefully addresses the problems and inserts the additional line you wanted. The added line is indented with two spaces as that’s how it comes off this forum page, but a tab can easily be used instead if the lines in the files are tab-indented.
set theSourceFolder to (choose folder with prompt "Select a folder:")
-- Select all the nfo files in the folder hierarchy.
tell application "Finder"
set filesArray to (every file of entire contents of theSourceFolder whose name ends with ".nfo") as alias list -- The Finder doesn't recognise "nfo" as a file extension on my machine. :\
end tell
tell application "TextWrangler"
activate
repeat with aFile in filesArray
set docName to name of (open aFile)
tell document docName
-- Set the document text to just the lines which need to be kept.
set its text to copied lines of (process lines containing matching string "(<\\?xml|<movie>|</movie>|</id>|</title>|<actor>|</actor>|</name>|</genre>|</year>|</tag>|</set>|</plot>)" with matching with grep)
-- Find the id text.
set idText to found text of (find "(?<=<id>)[^<]*+(?=</id>)" options {search mode:grep, starting at top:true})
-- Replace the title with the id text.
replace "(?<=<title>)[^<]*+(?=</title>)" using idText options {search mode:grep, starting at top:true}
-- Replace the "</movie>" line with another line and it.
replace "</movie>" using " <genre>FAVORITES</genre>" & linefeed & "</movie>" options {wrap around:true}
-- Save and close the document.
close saving yes
-- Ensure the document's gone before opening another.
repeat while (it exists)
delay 0.2
end repeat
end tell
end repeat
end tell
There are various ways in which a script can edit the text of a file without having to open it in an application’s visible document. I’ll see if I can put an example together this afternoon. To judge from TextWrangler’s scripting dictionary, it can itself edit batches of files in situ, but I can’t see how to script that.
Here’s a “vanilla” version, which is more code, but faster. Like the TextWrangler script, it assumes that the text between the tags doesn’t include any linefeeds or returns.
set theSourceFolder to (choose folder with prompt "Select a folder:")
-- Select all the nfo files in the folder hierarchy.
tell application "Finder"
set filesArray to (every file of entire contents of theSourceFolder whose name ends with ".nfo") as alias list -- The Finder doesn't recognise "nfo" as a file extension on my machine. :\
end tell
set requiredKeys to {"movie", "movie", "id", "title", "actor", "name", "genre", "year", "tag", "set", "plot"}
set astid to AppleScript's text item delimiters
repeat with aFile in filesArray
-- Open an access channel to this file.
set fRef to (open for access aFile with write permission)
try
-- Read the file, assuming its contents to be UTF-8 text, and get a list of the lines.
set textLines to paragraphs of (read fRef as «class utf8»)
-- Set AppleScripts text item delimiters to the XML tag delimiters.
set AppleScript's text item delimiters to {"</", "<", ">"}
-- Treat each line according to the contents of its first tag label.
repeat with i from 1 to (count textLines)
set thisLine to item i of textLines
set tagLabel to text item 2 of thisLine
if (tagLabel is "title") then
-- Note the title line number.
set titleLineIndex to i
else if (tagLabel is "id") then
-- Note the ID value.
set theID to text item 3 of thisLine
else if (thisLine contains "</movie>") then
-- Insert an extra "<genre>" line before the "</movie>" one.
set item i of textLines to (" <genre>FAVORITES</genre>" & linefeed & thisLine)
else if not ((tagLabel is in requiredKeys) or (tagLabel begins with "?xml")) then
-- Zap any unwanted line.
set item i of textLines to missing value
end if
end repeat
-- Replace the title in the title line with the ID value.
set oldTitleLine to item titleLineIndex of textLines
set newTitleline to text 1 thru text item 2 of oldTitleLine & ">" & theID & "<" & text from text item 4 to -1 of oldTitleLine
set item titleLineIndex of textLines to newTitleline
-- Reunite the unzapped lines as a single text.
set AppleScript's text item delimiters to linefeed
set editedText to (textLines's text) as text
-- Write this text back to the file.
set eof fRef to 0
write editedText as «class utf8» to fRef
-- Close the access channel.
close access fRef
on error errMsg
-- If there's an error, close the file and explain the problem.
close access fRef
set AppleScript's text item delimiters to astid
display dialog errMsg
end try
end repeat
set AppleScript's text item delimiters to astid