Add line numbers to text file

I’m in need of a script like this one listed below to add line numbers to a text file. I copied the script and tried to compile but got an error
Expected expression, “)”, but found unknown token.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
--https://www.macscripter.net/t/need-help-on-numbering-lines-in-textedit/26235


set the_file to (“” & (path to desktop) & “mytext.txt”)
set all_lines to paragraphs of (read file the_file)

repeat with i from 1 to (count all_lines)
set the_num to “” & i & “-” & item i of all_lines
if i < 10 then set the_num to “0” & the_num
set item i of all_lines to the_num
end repeat

tell (a reference to my text item delimiters)
set {old_delim, contents} to {contents, return}
set {all_lines, contents} to {“” & all_lines, old_delim}
end tell

–to write it it back to the file, uncomment the next line:
–do shell script "echo " & (quoted form of all_lines) & " > " & (quoted form of POSIX path of the_file)
return all_lines

The file I want to add line numbers is on my desktop and is named added-date.txt.
If someone could explain what I’d need to do to make this work it would be most appreciated.

Hi.

There are some smart quotes in there and a couple of incorrect comment markers. It’ll compile in this form:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
--https://www.macscripter.net/t/need-help-on-numbering-lines-in-textedit/26235


set the_file to ("" & (path to desktop) & "mytext.txt")
set all_lines to paragraphs of (read file the_file)

repeat with i from 1 to (count all_lines)
	set the_num to "" & i & "-" & item i of all_lines
	if i < 10 then set the_num to "0" & the_num
	set item i of all_lines to the_num
end repeat

tell (a reference to my text item delimiters)
	set {old_delim, contents} to {contents, return}
	set {all_lines, contents} to {"" & all_lines, old_delim}
end tell

--to write it it back to the file, uncomment the next line:
--do shell script "echo " & (quoted form of all_lines) & " > " & (quoted form of POSIX path of the_file)
return all_lines

Perfect. I appreciate your help!

Another nice example.

So I have a general question regarding creation of .txt doc’s. I have several text files on my desktop and I can’t remember what script generated them. Is there a “Simple” way to add a header to scripts that produce text files?
I have several that I have been able to figure out how to add text inside quotes to include the script. EXAMPLE: “SCRIPT ABC generated this text on 03/19/24”.
Any suggestions would be welcome.

The code below will produce output that looks like this atop the frontmost textedit document, assuming in this example that the script involved is named ‘mutt’:

SCRIPT MUTT generated this text on 2024/03/20

Save this in a script in Home > Library > Script Libraries, where it will be out of the way.

-- n should be name of calling script
on labeller(n)
	set docTitle to upCase(n) -- convert script file name to upper case
	set ds to formDate() -- get today as date string
	
	set headString to "SCRIPT " & docTitle & " generated this text on " & ds & linefeed & linefeed
	-- includes two trailing linefeeds to provide spacing
	
	-- NB textedit's undo does not undo this action
	tell application "TextEdit"
		activate
		make new paragraph at before paragraph 1 of document 1 with data headString
	end tell
end labeller

-- convert case to upper
on upCase(n)
	-- set text item delimiters to ""
	set charList to characters of n
	set c to length of n
	
	repeat with nc from 1 to c -- cycle through each character in file name
		set cid to id of item nc of n
		-- change case of letter to UPPER
		if cid is greater than 96 and cid is less than 123 then
			set item nc of charList to character id (cid - 32)
		end if
	end repeat
	return charList as text
end upCase

-- return date as string yyyy/mm/dd
on formDate()
	set sds to short date string of (get current date)
	set text item delimiters to {"/", "-"}
	set sds to text items of sds as text -- convert dashes to slashes
	set text item delimiters to ""
	return sds
end formDate

(*
Note on undo: The addition of the paragraph isn't affected by ¬
TextEdit's undo. If you wish to remove the added text (or make some ¬
other change), simply delete it (or edit normally). Using undo will ¬
instead undo whatever action you last performed in TextEdit.
*)

Then put this inside whatever script you want to have this ability, below wherever your text file creating code is.

tell script "libLabeller" to labeller(name of me) -- name of this script, by any means

There are probably other and better ways to call a script but this is one I know so…
Of course, you could put both pieces into any script but that’s kind of an ugly solution.

1 Like

I appreciate the help. I’ll experiment with this to see if I can get it to work.
Thanks

My pleasure. Let me know if you have any questions about the code. It’s actually simpler than it may appear.

In addition to using it in whatever script you like, you can call it from a script that contains only this single line:

tell script "libLabeller" to labeller(name of me)

This may make it easier to try out. It will launch textedit if it’s not open, but if it’s already running, make sure there is an open document (even a blank one).

Also, I was just thinking that your date format is what it is. You could replace the existing on formDate() handler with this one to get the mm/dd/yyyy format in the result. If you’re seeing different results with the date, let me know as the computer’s date settings may play a role.

-- return date as string mm/dd/yyyy
on formDate()
	set sds to short date string of (get current date)
	--> "2024-03-20"
	set text item delimiters to {"/", "-"}
	set sds to text items of sds
	--> {"2024", "03", "20"}
	set sds to {item 2 of sds, item 3 of sds, item 1 of sds}
	--> {"03", "20", "2024"}
	set text item delimiters to "/"
	set sds to sds as text
	set text item delimiters to ""
	return sds
end formDate
--> "03/20/2024"

Thanks, I’ll play with this one too. Do I need to store in the library like the previous one?

I tried your handler and after some experimentation, got it to work.
SCRIPT ANOTHER FOLDER TO TEXT generated this text on 3/21/24

Folders:

Files:
logger.scpt

--Added to library on 10/04/2023
--This script is another version of folder content to text file
--https://www.macscripter.net/t/if-my-counter-0-then-display-dialog-yields-error/58891/8


set the_folders to {}
set the_files to {}

set my_folder to choose folder
tell application "Finder"
	set my the_folders to the name of every folder in folder my_folder
	set my the_files to the name of every file in folder my_folder
end tell
set folder_count to (count my the_folders)
set file_count to (count my the_files)
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
set my the_files to my the_files as text
set my the_folders to my the_folders as text
set AppleScript's text item delimiters to tids
tell application "TextEdit"
	activate
	make new document at the front
	
	set text of front document to "Folders:" & return & my the_folders & return & "Files:" & return & my the_files
	tell script "libLabeller" to labeller(name of me)
	
	set myword to a reference to first word of text of document 1
	set font of myword to "Helvetica-Bold"
	tell text of document 1
		set secword to a reference to item 1 of (every word where it is "Files")
	end tell
	set font of secword to "Helvetica-Bold"
end tell
tell application (path to frontmost application as string)
	display dialog "There is a total of " & file_count + folder_count & " items in the folder:" & return & my_folder & return & return & "There are " & file_count & " file(s) and " & folder_count & " folder(s)." buttons {"OK"} default button 1
end tell

I tried inserting it in the 3rd row of code and it errored out. I moved it to where it now resides and seems ok. Pretty Slick.

Looks good. Glad it works.

Some mild tweaks to consider. First, it’s not necessary (or really advantageous) to set the_folders/files to {} at the beginning of the script. Generally, this is done when you need a list but the actions in the script won’t automatically produce a list, for example, without doing this, the set end of theList to x inside a repeat loop generates an error. In this case however, the way the name of every… command works, the list is created automatically.

And for the textedit block… the make new command can automatically generate a variable to reuse. This is generally more stable as document 1 can change whereas the variable will not. It is then used for the word/font changes.

tell application "TextEdit"
	activate
	set ndoc to make new document at the front
	
	set text of ndoc to "Folders:" & return & the_folders & return & "Files:" & return & the_files
	tell script "libLabeller" to labeller(name of me)
	
	set myword to a reference to first word of text of ndoc
	set font of myword to "Helvetica-Bold"
	
	set secword to a reference to item 1 of (every word of ndoc where it is "Files")
	set font of secword to "Helvetica-Bold"
end tell

set diagText to "There is a total of " & file_count + folder_count & " items in the folder:" & return & my_folder & return & return & "There are " & file_count & " file(s) and " & folder_count & " folder(s)."
tell me to display dialog diagText buttons {"OK"} default button 1 giving up after 8

Thanks for the tips. I have implemented a couple of you tips into my scripts. I do have another question however.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

-- Handler to count items in a list and write the count to a text file
on countAndWriteToFile(itemList, outputPath)
	set itemCount to count of itemList
	
	-- Convert the item count to text
	set itemCountText to itemCount as text
	set Cost to itemCount * 17.0 as text
	
	-- Write the item count to the specified file
	try
		set fileDescriptor to open for access outputPath with write permission
		write itemCountText & Cost to fileDescriptor
		close access fileDescriptor
		display dialog "Item count has been written to the file." buttons {"OK"} default button "OK"
	on error errMsg
		close access fileDescriptor
		display dialog "An error occurred: " & errMsg buttons {"OK"} default button "OK"
	end try
end countAndWriteToFile

-- Example usage:
set myList to {"jan 20", "Feb 26", "Mar 29", "April 8"} -- Replace with your list of items
set outputFile to (path to desktop as text) & "0407 ItemCount.txt" -- Replace with your desired output file path

countAndWriteToFile(myList, Cost, outputFile)
--Get error here with Cost variable not define but I defined above? Don't understand error messgae

I’m trying to take the count of items in my list and multiply it by 17 and write the total along with mylist to the text file. I get an error that the variable Cost is not defined. I Don’t understand error messgae

So, actually you haven’t. The bottom line (in which you call the handler) is feeding parameters to the handler but does not know the results until they are returned — after it has completed.

In a logical sense, you are trying to tell the handler what the cost is even while you are trying to get the cost from the handler.

What happens if you use this instead:

countAndWriteToFile(myList, outputFile)

I ran it the way you suggested and Bingo, it works. I need to add another linefeed but it generated what I was looking for.

I also have been playing with the `libLabeller" to labeller(name of me) script and have utilized it in many on my text scripts. In others, I already had found a simple solution to add the script name into the header of the file. I have not messed with the date examples or the last bit of code you suggested.

I’m trying to get more efficient with these scripts, but sometimes I can’t get out my own way. I do appreciate the folks here who lend a hand to the less experienced. I

Glad it works and was easy to modify.

Much of what I know about using applescript, I’ve learned by reading posts here, seeing how others solved issues and trying to figure out solutions on my own. The site is a great resource.

Just to add, there’s a shell command for adding line numbers to a text file.

do shell script "nl -w2 -s' ' ~/Desktop/mytext.txt | awk '{printf "%02d %s\n", $1, $2}'"