Insert escape backslash before quotation marks in string?

I am writing a script that asks the user to select a file and then writes the POSIX path of the file to a defaults file, something like this (with only the essential steps include):


set macOpen to choose file
set macPosix to quoted form of POSIX path of macOpen
do shell script "defaults write org.myorg.myprogram origpath" & space & macPosix

If the macPosix variable contains quotation marks (because quotation marks are legal in OS X filenames), then the “defaults write” command fails with a message suggesting that I try single quotes. So I tried this instead:


set macOpen to choose file
set macPosix to "'" & POSIX path of macOpen & "'"
do shell script "defaults write org.myorg.myprogram origpath" & space & macPosix

But it failed the same way.

Is there a command or applescript routine that will take this string:

/Users/roscoe/this is “my file” name.doc

and return this one:

/Users/roscoe/this is "my file" name.doc

so that I can use it in the “defaults write” command?

As far as I know, the best way to get rid of that is to use the feature officially delivered to do that :

set macOpen to choose file
set macPosix to quoted form of POSIX path of macOpen # EDITED
do shell script "defaults write org.myorg.myprogram origpath" & space & macPosix

Yvan KOENIG running El Capitan 10.11.4 in French (VALLAURIS, France) dimanche 27 mars 2016 16:14:21

Yvan,

Thank you, but your edited version seems to be exactly the same as the first script in my post. The defaults write command produces an error message if the file that I select has quotation marks in its name like this:

Please try it. I copied your script into the Script Editor, ran it, chose a file with quotation marks in the filename, and got the same error message I got before.

I think I still need a routine that will add escape characters preceding the quotation marks.

EDIT: I’ve been experimenting with the sed command, but can’t get anything to work, probably because i’m too ignorant. I think awk or perl may also do the job, but I can’t figure out the syntax, and will be grateful for any help.

I’ve made a little progress, I think, but would still be grateful for some AppleScript help. This command produces the correct results in the terminal:

The result is:

But I can’t figure out how to add escapes to the filename and to the awk command so that I could use a shell script to write the string to a defaults file.

And I’m not at all sure that this is the right way to do it!

Try to apply quoted form twice.

set macOpen to choose file
set macPosix to quoted form of (POSIX path of macOpen) # EDITED

--do shell script "cp " & macPosix & space & quoted form of POSIX path of (path to documents folder as text)
do shell script "defaults write org.myorg.myprogram origpath" & space & (quoted form of macPosix)

When I ran it I got :

tell application "Script Editor"
	choose file
end tell
(*'/Users/userName/Desktop/pour "Alain" Croughs.scpt'*)
tell current application
	do shell script "defaults write org.myorg.myprogram origpath ''\\''/Users/userName/Desktop/pour \"Alain\" Croughs.scpt'\\'''"
end tell

Yvan KOENIG running El Capitan 10.11.4 in French (VALLAURIS, France) dimanche 27 mars 2016 18:18:16

Yvan,

Thank you! This helps enormously, but it leaves me with a further problem, and I hope you’re feeling generous enough to help solve it.

Here is a sample script:

set deskPosix to POSIX path of (path to desktop)
set macOpen to choose file
set macPosix to POSIX path of macOpen
do shell script "defaults write org.myorg.myprogram origpath" & space & quoted form of (quoted form of macPosix)
set filepath to do shell script "defaults read org.myorg.myprogram origpath"
set copypath to deskPosix & "test.file"
do shell script "cp -f" & space & quoted form of filepath & space & copypath

If I choose a file with “quotation marks” in the name, this works perfectly.

If I choose a file with no quotation marks in the name, I get an error message:

(Notice the single quotes around the file name.)

Is there a way to write this script so that it can handle filenames with and without quotation marks?

I think this may be the answer to my question, but probably Yvan or some other expert will have a better answer:

set deskPosix to POSIX path of (path to desktop)
set macOpen to choose file
set macPosix to POSIX path of macOpen
do shell script "defaults write org.myorg.myprogram origpath" & space & quoted form of (quoted form of macPosix)
set filepath to do shell script "defaults read org.myorg.myprogram origpath"
if character 1 of (filepath as string) is "'" then
	set filepath to (characters 2 thru -2 of filepath as string)
end if
set copypath to deskPosix & "test.file"
do shell script "cp -f" & space & quoted form of filepath & space & copypath

The “if” block seems to resolve the problem - it tests for an opening single quotation mark, which presumably can never be the first character in an actual filename; it can only occur in a quoted form of a filename.

Is there a better way to accomplish this?

Hey There,

You’ve got a lot of confusion going on with quotes.

Dealing with quoting in the shell and quoting in AppleScript can be very confusing indeed.

The best way to manage that is to NEVER use a bare do shell script statement when developing.

Take something like this with complex quoting issues:

[format]#!/usr/bin/env bash
sourceDIR=~/“test_directory/KM_TEST/”;
destinatinDIR=~/“Downloads/Dest/”;
cd “$destinatinDIR”;
fileList=$(‘ls’ -1 $sourceDIR | sed -E ‘s!.[^.]+$!!; s!^!’“'”‘!; s!$!’“'”‘!’ | paste -sd “,” -);
eval mkdir {$fileList};[/format]

So, I’ve created a command-string that I can export to BBEdit or TextWrangler or the clipboard and eyeball without all the extra AppleScript quoting.


set shCMD to text 2 thru -1 of "
#!/usr/bin/env bash
sourceDIR=~/\"test_directory/KM_TEST/\";
destinatinDIR=~/\"Downloads/Dest/\";
cd \"$destinatinDIR\";
fileList=$('ls' -1 $sourceDIR | sed -E 's!\\.[^.]+$!!; s!^!'\"'\"'!; s!$!'\"'\"'!' | paste -sd \",\" -);
eval mkdir {$fileList};
"

set the clipboard to shCMD

# do shell script shCMD

Once the exported version matches the original I know I’ve got all my quoting issues solved.

When I develop shell scripts I never do it in the Script Editor (or Script Debugger in my case) I always use the Terminal or a BBEdit worksheet. (TextWrangler or any other editor that will run shell scripts will work as well.)

Only when I get something working do I start translating it to AppleScript.

This methodology has saved me many hours of grief.


Best Regards,
Chris


{ MacBookPro6,1 · 2.66 GHz Intel Core i7 · 8GB RAM · OSX 10.11.4 }
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

I would use :

set deskPosix to POSIX path of (path to desktop)
set macOpen to choose file
set macPosix to POSIX path of macOpen
if macPosix contains quote then
	do shell script "defaults write org.myorg.myprogram origpath" & space & quoted form of (quoted form of macPosix)
else
	do shell script "defaults write org.myorg.myprogram origpath" & space & quoted form of macPosix
end if
set filepath to do shell script "defaults read org.myorg.myprogram origpath"
set copypath to deskPosix & "test.file"
do shell script "cp -f" & space & quoted form of filepath & space & copypath

or, same code written differently :

set deskPosix to POSIX path of (path to desktop)
set macOpen to choose file
set macPosix to POSIX path of macOpen
if macPosix contains quote then set macPosix to quoted form of macPosix
do shell script "defaults write org.myorg.myprogram origpath" & space & quoted form of macPosix
set filepath to do shell script "defaults read org.myorg.myprogram origpath"
set copypath to deskPosix & "test.file"
do shell script "cp -f" & space & quoted form of filepath & space & copypath

Yvan KOENIG running El Capitan 10.11.4 in French (VALLAURIS, France) dimanche 27 mars 2016 22:42:33

Hello Yvan,

Your version is - as I hoped and expected - more elegant and efficient, and does the job perfectly. Thank you!