1

I have a .txt file saved on my computer. I want Automator to add a bit of text to the very top of the .txt file. I do not want any text in the .txt file to be overwritten. I also want a new line to be created for the new text.

The following command adds the text to the .txt file, but at the end of the file:

set TextToWrite to "This sentence should be the first line of the .txt file."
set TargetFilepath to "/Users/Me/Desktop/Documents/My File.txt"
do shell script "echo " & quoted form of TextToWrite & " >> " & quoted form of TargetFilepath

Can prepending to a .txt file be accomplished in AppleScript? Thank you.


Update:

I have discovered a pernicious little bug in all of the current 4 answers to this question.

Blank lines in a .txt file created on a Mac should show up as 0A0A in a hex editor. But, for whatever reason, the answers provided by Matteo, Christian Boyce, and user3439894 convert blank lines into 0D0D. In practice, 0D0D produces an identical result to 0A0A -- they both look like a blank line -- but Mac perceives 0D0Das a carriage return while Mac perceives 0A0A as a line feed.

Here's the test that I did to discover this issue in the answers provided by Matteo and user3439894 (and if you do the same, you can reproduce the issue):

  1. Create a New Document in TextEdit. Click "Make Plain Text" in the Format menu. Save the empty file as a .txt file.

  2. Run the AppleScript code provided by Matteo, Christian Boyce, or user3439894 using this .txt file as TargetFilepath.

  3. Open the .txt file in TextEdit and manually add a blank line to the file by using your Enter key.

  4. Open the .txt file in your hex editor and confirm that this new blank line is 0A0A.

  5. Run the AppleScript code again.

  6. Open the .txt file in your hex editor. You will now notice that the 0A0A has been converted to 0D0D.

Here's the test that I did to discover this issue in the answer provided by Christian Boyce:

  1. Create a New Document in TextEdit. Type "This is a sentence.". The file cannot be empty if you want run the code provided by Christian Boyce without error. Click "Make Plain Text" in the Format menu. Save the file as a .txt file.

  2. Run the AppleScript code that Christian Boyce provided. When asked to choose a file, open this .txt file.

  3. Open the .txt file in TextEdit and manually add one blank line in between the new "Wassup?" line and the original "This is a sentence" line by using your Enter key.

  4. Open the .txt file in your hex editor. Notice that this new blank line is 0A0D. It should be, however, 0A0A. So, while the answer provided by Christian Boyce does not change all instances of 0A0A to 0D0D (in the way that the answers provided by Matteo and user3439894 do), it does use 0D instead of 0A when putting "Wassup?" on a new line.

It took me a long time to discover this glitch, as one could never tell that there was a problem with these AppleScript solutions unless one opens the .txt file in a hex editor.

The problem with the answer provided by Mateusz Szlosek is more severe; it replaces all instances of 0A0A with 20, thereby ensuring that there are no blank lines anywhere in the .txt file (which, unlike the other answers, meant that I could easily identify that it had a bug without opening the .txt file in a hex editor).

So, I am re-opening this question, now hoping that someone can provide a way to prepend text to a .txt file using AppleScript, and without converting line feeds to carriage returns in the process.

If you are curious why I need the line feeds to be preserved, it is because I have a later process that writes to the first blank line of the .txt file, and this process does not work properly if the line feeds are replaced with carriage returns.

  • Here's the acid test, so to speak... Writing the representative code in a bash script and running it in Terminal alone produces the expected and wanted results of having just line feeds not carriage returns whether starting with a zero length file or a file that already has ASCII Text content. The introduction of carriage returns when using AppleScript's do shell script command with the same bash commands in this use case would have to be considered a bug, due to the fact that it is not producing the expected behavior. Continued in next comment... – user3439894 Nov 28 '16 at 17:54
  • Therefore I would not use this methodology to write to files and instead use the other methods AppleScript offers. I have already shown you an example in apple.stackexchange.com/questions/260424/… and suggest you implement it as it does not introduce unwanted carriage returns into the document. – user3439894 Nov 28 '16 at 17:54
  • @user3439894 Thanks for the analysis. I don't know how to modify your code that writes to the first instance of a blank line so that the code instead writes to the very top of the document. The answer provided by Christian Boyce does not have a do shell script command anywhere in it. Can you tell me if my answer is okay to use? – rubik's sphere Nov 28 '16 at 20:36
  • I've update my answer (again). :) – user3439894 Nov 28 '16 at 23:40
1

Updated Answer:

The code below it what I'd use to replace the original code offered as there appears to be a bug in AppleScript when using the do shell script command in the manner originally presented that isn't present went the code, in a representative manner, is run in a bash script in Terminal.

Note that anytimeopen for access is used, it needs to be coded to trap any errors and try and close the file, which this attempts to do. That said it is not necessarily then only error handling I'd employ and all coding answer I present are done so as proof of concept and the onus to write code employing reasonable error handing is yours to fulfill.

As coded, this will create the target file if it doesn't exist while adding the text to add to it and if it does exist, places the text to add as the top line of the target file.

set targetFilePathname to (POSIX path of (path to desktop as string) & "My Fruit Log.txt")

--    # set theTextToWrite to "This text will be written at the top of the file." & "\n"    
set theTextToWrite to "This text will be written at the top of the file." & "\n"
set theOriginalText to ""
try
    set theOriginalText to (read targetFilePathname) as string
end try
--    # set theTextToWrite to theTextToWrite & "\n" & theOriginalText
set theTextToWrite to theTextToWrite & "\n" & theOriginalText
try
    set referenceNumber to open for access targetFilePathname with write permission
    write theTextToWrite to referenceNumber starting at 0
    close access referenceNumber
on error eStr number eNum
    display dialog eStr & " number " & eNum buttons {"OK"} default button 1 with title "File I/O Error..." with icon caution
    try
        close access referenceNumber
    end try
    return
end try
  • I think I may have found the root cause of the 0D0D issue. Please do the following: 1. Create an empty plain text .txt file in TextEdit. 2. Run your script using this .txt file as TargetFilepath. 3. Open the .txt file in your hex editor. You will notice that the last four hex characters are 0A0A (so far so good). 4. Manually open the .txt file in TextEdit. Create a new blank line beneath the sample sentence using your Enter key. 5. Run your script for the second time. 6. Open the .txt file in your hex editor. You will now notice that the 0A0A has been converted to a 0D0D. – rubik's sphere Nov 28 '16 at 6:43
  • In other words, your code takes any previously-written instances of 0A0A and replaces them all with 0D0D. To be clear, it's not just your code; the codes that Matteo and @Christian Boyce provided behave similarly. The code provided by Mateusz Szlosek is even worse; upon running, it replaces all instances of 0A0A with 20. – rubik's sphere Nov 28 '16 at 6:45
1

You could do it this way, avoiding the shell scripts.

set the_file to choose file
set the_content to read of the_file

set the_new_stuff to "Wassup?" & return & the_content
set the_file_path to the_file as string
set open_for_writing to open for access file the_file_path with write permission
write the_new_stuff to open_for_writing starting at 0
close access open_for_writing

Basically you read the text in the .txt file, you put "Wassup?" and a return in front of the text, and then you write over what's in the file (because you start at position 0).

1

You could copy the current content of the file to a variable, then copy TextToWrite to TargetFilePath and then append the previous content back to TargetFilePath.

set x to (do shell script "cat " & quoted form of TargetFilePath)

do shell script "echo " & quoted form of TextToWrite & " > " & quoted form of TargetFilePath

do shell script "echo " & quoted form of x & " >> " & quoted form of TargetFilePath
0

Here's an example of the AppleScript You can use:

set TargetFilepath to "$HOME/Desktop/file.txt"
set TextToWrite to quoted form of "NewText\n"
do shell script "echo " & TextToWrite & "$(cat " & TargetFilepath & ") > " & TargetFilepath

It uses the formula: echo "prepend\n $(cat input)" > input

  • This code successfully prepends the text. Is it possible to create a new line in the .txt file for the new text (as requested)? – rubik's sphere Nov 9 '16 at 1:00
  • 1
    @rubik's sphere, Change set TextToWrite to "NewText" to set TextToWrite to quoted form of "NewText\n" and when it compiles the \n will become a literal new line with the closing quote literally on the next line and the \n disappears. – user3439894 Nov 9 '16 at 2:56
  • @user3439894 thanks for a hint, I've added this to my answer. – Mateusz Szlosek Nov 9 '16 at 3:30
  • @user3439894 Thanks, your fix worked. @ MateuszSzlosek I have discovered that your code messes with the original formatting of the .txt file. For example, it randomly removes line breaks in the middle of the document. Try running your code with a .txt file that has a few paragraphs of text and empty line breaks in-between the paragraphs. Do you see what I am talking about? – rubik's sphere Nov 9 '16 at 3:39
0

After a lot of trial and error, I think I have found one way to prepend text to a .txt file without carriage returns being introduced into the .txt file.

My solution is built on the solution provided by @Christian Boyce, with just one small change: replace return with "\n".

So, the full solution would be:

set the_file to choose file
set the_content to read of the_file

set the_new_stuff to "Wassup?" & "\n" & the_content
set the_file_path to the_file as string
set open_for_writing to open for access file the_file_path with write permission
write the_new_stuff to open_for_writing starting at 0
close access open_for_writing

I have done tests with this code and I have not found it to insert 0D into the document and nor does it change any instances of 0A to 0D.

  • @user3439894 Can you please let me know how you feel about this solution? Is it good? – rubik's sphere Nov 28 '16 at 16:15
  • No it is not, as it does not employ any or property error handling! See my updated answer to apple.stackexchange.com/questions/262687/… especially Part 4. Anytime you use open for access it needs to be coded to trap any errors and try and close the file. This is how I coded it in the link I'm pointing you to the answer of another one of your questions. – user3439894 Nov 28 '16 at 22:43

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.