AppleScript to replace text in multiple files - perl

I'm trying to come up with a general multi-purpose way of replacing text in multiple files through AppleScript. This solution is using Perl. Is there maybe a more elegant way of doing this?
set myFolder to choose folder with prompt "Choose a folder:"
tell application "Finder"
try
set txtFiles to (every file in entire contents of myFolder whose name ends with ".txt") as alias list
on error
try
set txtFiles to ((every file in entire contents of myFolder whose name ends with ".txt") as alias) as list
on error
set txtFiles to {}
end try
end try
set myFiles to txtFiles
end tell
repeat with CurrentFile in myFiles
set CurrentFile to CurrentFile as string
do shell script "perl -pi -e 's/replace/me/g; s/andme/too/g;' " & quoted form of (POSIX path of CurrentFile)
end repeat
Also, ideally, I'd like to make the Perl part a bit more readable, having each search/replace pattern on a separate line, but the do shell script in AppleScript seems to be unable to deal with line breaks, e.g.,
do shell script "perl -pi -e '
s/replace/me/g;
s/andme/too/g;
s/andhere/measwell/g;
' " & quoted form of (POSIX path of CurrentFile)
So essentially, is there a better/more elegant way of doing this?
Doesn't necessarily have to be with perl, yet for a non-expert I continue to find perl the easiest way for handling this, especially as it's great at regexes (the solution should be able to do regexes).

According to this, you could use
do shell script "perl -pi -e '" & ¬
" s/replace/me/g;" & ¬
" s/andme/too/g;" & ¬
" s/andhere/measwell/g;" & ¬
"' " & quoted form of (POSIX path of CurrentFile)
Pardon my lack of knowledge of AppleScript, but maybe you can even do something like the following:
set PerlProg to "" & ¬
"s/replace/me/g; " & ¬
"s/andme/too/g; " & ¬
"s/andhere/measwell/g;"
set PerlCmd to "perl -i -pe'" & PerlProg & "'"
do shell script PerlCmd & " " & quoted form of (POSIX path of CurrentFile)

Related

Apple script – replace with hyperlink in document without opening

I need to replace 400+ words with different hyperlinks in a rtf- or .docx-document.
I’ve made a script using keystrokes (cmd+f, esc etc), but the script takes forever and is not stable enough.
Using sed -i I’m able to do a replacement of the word, but not with hyperlink. Is this possible?
set theFile to choose file
set original to "foo"
set substitute to "VG"
set newlink to "https://www.vg.no"
do shell script "sed -i '' \"s|" & original & "|" & substitute & "|g\" " & quoted form of (POSIX path of theFile)
Here is something specific to try:
First, create a rich text document with the word 'foo' as its content (in TextEdit, as Word's output is an abomination). Save the file in the appropriate place and run this:
set theFile to ((path to desktop) as text) & "slink3.rtf"
set qptf to quoted form of POSIX path of theFile
set origStr to "foo"
set subStr to "VG"
set newlink to "https://www.vg.no"
do shell script "sed -i '' -e 's|" & origStr & "|" & subStr & "|' -e 's|VG|{{\\\\*\\\\fldinst{HYPERLINK \"https://www.vg.no/\"}}{\\\\fldrslt VG}}|' " & qptf
This expands to:
do shell script "sed -i '' -e 's|foo|VG|' -e 's|VG|{{\\\\*\\\\fldinst{HYPERLINK \"https://www.vg.no/\"}}{\\\\fldrslt VG}}|' '/Users/username/Desktop/slink3.rtf'"
The actual shell command which runs is:
% sed -i '' -e 's|foo|VG|' -e 's|VG|{{\\*\\fldinst{HYPERLINK "https://www.vg.no/"}}{\\fldrslt VG}}|' '/Users/username/Desktop/slink3.rtf'
What it does is first replace the string foo with the string VG, and then replace the string VG with VG as hyperlinked text.
NB TextEdit has a preference to display the raw rtf upon opening a file rather than the formatted text. If you do this with a document containing a single word, the structure is relatively clear. I recommend against even looking at a Word-generated document.
If you do this, you will see that the raw rtf uses a single backslash but both the shell and applescript require escaping which is why the script has \\\\.
Incidentally, I notice that you finish your sed search with 'g' but shouldn't this only run once per line? Consider removing it.
Obviously, I don't know your entire workflow but hopefully this matches the section you have posted.

Explain batch command please

I want to create a folder with the name of the current date and time.
After searching a lot i found this which actually works.
Can someone explain what these batch commands do?
set timestamp=%DATE:/=-%#%TIME::=-%
set timestamp=%timestamp: =%
mkdir "%timestamp%"
Insert echo statements between the lines and you can see what the value of timestamp is
set timestamp=%DATE:/=-%#%TIME::=-%
echo %timestamp%
set timestamp=%timestamp: =%
echo %timestamp%
mkdir "%timestamp%"
Basically, the code is just removing the forward slash from the date and the colon from time since those are not valid directory names replacing them with hypens.
Read set /? Environment variable substitution to get a better idea.
set timestamp=%DATE:/=-%#%TIME::=-%
That's a string replacement.
1st:
%DATE:/=-% Replaces "/" character to "-" character in the DATE variable
(See: Echo %DATE% on your console)
2nd:
Adds the "#" character to the string after the DATE var and before the TIME var.
3rd:
%TIME::=-% Replaces ":" character to "-" character.
(See: Echo %Time% on your console)
set timestamp=%timestamp: =%
Next in that replacement replaces itself spaces to any characarter (so deletes spaces), but really any space is given so is not necessary in your example code.
You can learn more about Variable string replacement here: http://ss64.com/nt/syntax-replace.html
Also you can simplify your code 'cause no need to setting the value first:
mkdir "%DATE:/=-%#%TIME::=-%"

Replacing text with apostrophe text via sed in applescript

I have an applescript to find and replace a number of strings. I ran in the problem of having a replacement string which contained & some time ago, but could get around it by putting \& in the replacement property list. However an apostrophe seems to be far more annoying.
Using a single apostrophe just gets ignored (replacement doesn't contain it), using \' gives a syntax error (Expected “"” but found unknown token.) and using \' gets ignored again. (You can keep doing that btw, even number gets ignored uneven gets syntax error)
I tried replacing the apostrophe in the actual sed command with double quotes (sed "s…" instead of sed 's…'), which works in the command line, but gives a syntax error in the script (Expected end of line, etc. but found identifier.)
The single quotes mess with the shell, the double quotes with applescript.
I also tried '\'' as was suggested here and '"'"' from here.
Basic script to get the type of errors:
set findList to "Thats.nice"
set replaceList to "That's nice"
set fileName to "Thats.nice.whatever"
set resultFile to do shell script "echo " & fileName & " | sed 's/" & findList & "/" & replaceList & " /'"
Try:
set findList to "Thats.nice"
set replaceList to "That's nice"
set fileName to "Thats.nice.whatever"
set resultFile to do shell script "echo " & quoted form of fileName & " | sed \"s/Thats.nice/That\\'s nice/\""
or to stick to your example:
set findList to "Thats.nice"
set replaceList to "That's nice"
set fileName to "Thats.nice.whatever"
set resultFile to do shell script "echo " & quoted form of fileName & " | sed \"s/" & findList & "/" & replaceList & "/\""
Explanation:
The sed statement is usually enclosed by single quotes like this:
set myText to "Hello"
set xxx to do shell script "echo " & quoted form of myText & " | sed 's/ello/i/'"
However, in this example you could have exluded the single quotes altogether.
set myText to "Hello"
set xxx to do shell script "echo " & quoted form of myText & " | sed s/ello/i/"
The unquoted sed statement will break down as soon a space is included.
set myText to "Hello"
set xxx to do shell script "echo " & quoted form of myText & " | sed s/ello/i there/"
--> error "sed: 1: \"s/ello/i\": unterminated substitute in regular expression" number 1
Since you can't include an apostrophe within a single quoted statement (even if you escape it), you can enclose the sed statement in double quotes like this:
set myText to "Johns script"
set xxx to do shell script "echo " & quoted form of myText & " | sed \"s/ns/n's/\""
EDIT
Lauri Ranta makes a good point that if your find or replace string contains escaped double quotes my answer won't work. Her solution is as follows:
set findList to "John's"
set replaceList to "\"Lauri's\""
set fileName to "John's script"
set resultFile to do shell script "echo " & quoted form of fileName & " | sed s/" & quoted form of findList & "/" & quoted form of replaceList & "/"
I'd also use text item delimiters. You don't have to include AppleScript's in the default scope or set the property back if it isn't used later.
set input to "aasearch"
set text item delimiters to "search"
set ti to text items of input
set text item delimiters to "replace"
ti as text
There's no easy way to escape the search or replace patterns if they can contain something that would be interpreted by sed.
set input to "a[a"
set search to "[a"
set replace to "b"
do shell script "sed s/" & quoted form of search & "/" & quoted form of replace & "/g <<< " & quoted form of input
If you have to use regular expressions, scripting languages like Ruby have methods for creating patterns from strings.
set input to "aac"
set search to "(a+)"
set replace to "\\1b"
do shell script "ruby -KUe 'print STDIN.read.chomp.gsub(Regexp.new(ARGV[0]), ARGV[1])' " & quoted form of search & " " & quoted form of replace & " <<< " & quoted form of input without altering line endings

Unable to echo specific line to a .vbs file

The command prompt complains that it is unable to recoqnize the command.So i was thinking i needed to escape something that looked like a start of a command to the echo with the ^ character.
This is the exact line:
echo Set link = Shell.CreateShortcut(DesktopPath & "\Beta.lnk")>>%temp%\CreateFirefoxBetaShortcut.vbs
I tried:
echo ^Set link = Shell.CreateShortcut(DesktopPath & "\Beta.lnk")>>%temp%\CreateFirefoxBetaShortcut.vbs
But no luck.Im puzzled by this because it correctly enters much more complex lines but for some reason it want's to treat this line as a command not a simple text.
I can post the full .vbs including the other lines if that helps somehow.
The ampersand ("&") character has a special meaning for "cmd". Therefore, it must be preceded with a caret ("^"), like this:
echo Set link = Shell.CreateShortcut(DesktopPath ^& "\Beta.lnk")>>%temp%\CreateFirefoxBetaShortcut.vbs

nmake - how to force echo command to output the tab character?

How to force echo command to output a tab character in MS nmake makefile?
Verbatim tabs inserted right into a string after echo command are removed by nmake and don't show up in the output file.
all :
#echo I WANT TO OUTPUT THE <TAB> CHARACTER HERE! > output.txt
You can use a variable with TAB char. Put this lines in your .bat file:
set tab=[stroke TAB char from your keyboard]
echo a%tab%b>yourfile.txt
Doing so, yourfile.txt will have text a[TAB]b
As a workaround, you can create a file containing the tab character, named input.txt (not using nmake), and then say:
all :
#copy /b input.txt output.txt
I assume you already have tried to put the tab inside quotes?
all:
#echo "<TAB>" > output.txt
DOS and Windows have ugly text support in native batch files :).
Here is nice way to do your task:
install Python interpretator
write simple script which appends character with specified code to file
call script wherever you want :)
Simple script:
'''
append_char.py - appends character with specified code to end of file
Usage: append_char.py filename charcode
'''
import os
import sys
filename = sys.argv[1]
assert os.path.exists(filename)
charcode = int(sys.argv[2])
assert 0 <= charcode <= 255
fh = open(filename, 'ab')
fh.seek(0, os.SEEK_END)
fh.write(chr(charcode))
fh.close()
using this script from batch file you can create any possible file in universe :)
output.txt:
<<output.txt
I WANT TO OUTPUT THE <TAB> CHARACTER HERE!
<<KEEP
<TAB> represents a literal tab character here of course.
I had the same need. I used the answer using the quotes around the character and just took it one step further.
{tab} means pressing the keyboard tab key in the text editor.
SET tab="{tab}"
SET tab=%tab:~1,1%
The second line extracts the middle character from the quoted string.
Now you can use the %tab% variable with ECHO and, I suspect, anywhere else it's needed.
ECHO %tab%This text is indented, preceded by a tab.
I suspect this technique could be used with other problem characters as well.