sed and Applescript shell script - strip character string - sed

I'm trying to use sed in a shell script in Applescript to strip this string - ?print=1 - from this html link in the variable the_html, which is my link
but this throws an error:
set new_html to do shell script "echo " & quoted form of the_html & " | sed s=?print=1= =g'"
Do I need to escape the "="?
Edit:
Works now. Applescript didn't like an = escaped with a \, but escaping the whole string works:
sed 's/?print=1//g'

Try this:
echo 'my link' | sed 's/?print=1/ /g'
Comments:
Put the HTML in quotes or escape it property
When using sed, you generally use slashes: 's/a/b/'

This works on my Mac:
echo 'my link' | sed 's=?print\=1= =g'
So the answer is, yes, you do need to escape the = since it is used an expression delimiter.

Yes. You need to escape the characters that have a special meaning. Now there are the standard regular expression special characters, and the character that you are using as a delimiter. So if you use = as the delimiter, you'll need to escape it with \.
Usually / is used as the delimiter. The exception is when you might be searching for /, which yields some pretty crazy and hard to read expressions with all the escaping. So if you're searching for /s, I'd suggest using a different character, but otherwise, stick to /.
To answer the immediate question, you might escape the =:
sed '=print\=1= =g'
or use the standard slash, without escaping the =:
sed '/print=1/ /g'

You don't need to escape '=' if using another sed separator like '/' or ','. But if you wish to get URL parameters:
With '?' prefix:
echo 'my link' \
| sed -e 's,.*\(?.*\)\".*,\1,'
Without the '?' :
echo 'my link' \
| sed -e 's,.*?\(.*\)\".*,\1,'
The best is also to split parameters:
$ echo 'my link' \
| sed -e 's,.*?\(.*\)\".*,\1,' -e 's,&,\n,g'
print=1
convert=4
Have fun ! :)

Related

How to replace \n by space using sed command?

I have to collect a select query data to a CSV file. I want to use a sed command to replace \n from the data by a space.
I'm using this:
query | sed "s/\n/ /g" > file.csv .......
But it is not working. Only \ is getting removed, while it should also remove n and add a space. Please suggest something.
You want to replace newline with space, not necessarily using sed.
Use tr:
tr '\n' ' '
\n is special to sed: it stands for the newline character. To replace a literal \n, you have to escape the backslash:
sed 's/\\n/ /g'
Notice that I've used single quotes. If you use double quotes, the backslash has a special meaning if followed by any of $, `, ", \, or newline, i.e., "\n" is still \n, but "\\n" would become \n.
Since we want sed to see \\n, we'd have to use one of these:
sed "s/\\\n/ /g" – the first \\ becomes \, and \n doesn't change, resulting in \\n
sed "s/\\\\n/ /g" – both pairs of \\ are reduced to \ and sed gets \\n as well
but single quotes are much simpler:
$ sed 's/\\n/ /g' <<< 'my\nname\nis\nrohinee'
my name is rohinee
From comments on the question, it became apparent that sed had nothing to do with removing the backslashes; the OP tried
echo my\nname\nis | sed 's/\n/ /g'
but the backslashes are removed by the shell:
$ echo my\nname\nis
mynnamenis
so even if the correct \\n were used, sed wouldn't find any matches. The correct way is
$ echo 'my\nname\nis' | sed 's/\\n/ /g'
my name is

sed replace using string containing backslashes

I need to replace text in a file with a Windows-style directory path containing backslash (REVERSE SOLIDUS) characters. I am already using an alternative expression delimiter. The backslashes appear to be treated as escape characters.
How can I keep the backslashes in the output?
$ echo DIR=foobar | sed -e "s#DIR=.*#$(cygpath -w $(pwd))#"
C:gwin64homelit
The desired output is:
C:\cygwin64\home\lit
You'll have to escape metacharacters in sed replacement pattern. Fortunately, there are only three of those: &, \, and a delimiter / (see this question and this). In your case, since you're using # for delimiter, you'll have to escape # instead of /.
You can create a helper shell function (like here):
escapeSubst() { sed 's/[&#\]/\\&/g'; }
and then pass your string through it before giving it to sed, like this:
$ echo DIR=foobar | sed -e "s#DIR=.*#$(cygpath -w $(pwd) | escapeSubst)#"
C:\cygwin64\home\lit

How to insert strings containing slashes with sed? [duplicate]

This question already has answers here:
Using different delimiters in sed commands and range addresses
(3 answers)
Closed 1 year ago.
I have a Visual Studio project, which is developed locally. Code files have to be deployed to a remote server. The only problem is the URLs they contain, which are hard-coded.
The project contains URLs such as ?page=one. For the link to be valid on the server, it must be /page/one .
I've decided to replace all URLs in my code files with sed before deployment, but I'm stuck on slashes.
I know this is not a pretty solution, but it's simple and would save me a lot of time. The total number of strings I have to replace is fewer than 10. A total number of files which have to be checked is ~30.
An example describing my situation is below:
The command I'm using:
sed -f replace.txt < a.txt > b.txt
replace.txt which contains all the strings:
s/?page=one&/pageone/g
s/?page=two&/pagetwo/g
s/?page=three&/pagethree/g
a.txt:
?page=one&
?page=two&
?page=three&
Content of b.txt after I run my sed command:
pageone
pagetwo
pagethree
What I want b.txt to contain:
/page/one
/page/two
/page/three
The easiest way would be to use a different delimiter in your search/replace lines, e.g.:
s:?page=one&:pageone:g
You can use any character as a delimiter that's not part of either string. Or, you could escape it with a backslash:
s/\//foo/
Which would replace / with foo. You'd want to use the escaped backslash in cases where you don't know what characters might occur in the replacement strings (if they are shell variables, for example).
The s command can use any character as a delimiter; whatever character comes after the s is used. I was brought up to use a #. Like so:
s#?page=one&#/page/one#g
A very useful but lesser-known fact about sed is that the familiar s/foo/bar/ command can use any punctuation, not only slashes. A common alternative is s#foo#bar#, from which it becomes obvious how to solve your problem.
add \ before special characters:
s/\?page=one&/page\/one\//g
etc.
In a system I am developing, the string to be replaced by sed is input text from a user which is stored in a variable and passed to sed.
As noted earlier on this post, if the string contained within the sed command block contains the actual delimiter used by sed - then sed terminates on syntax error. Consider the following example:
This works:
$ VALUE=12345
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345
This breaks:
$ VALUE=12345/6
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
sed: -e expression #1, char 21: unknown option to `s'
Replacing the default delimiter is not a robust solution in my case as I did not want to limit the user from entering specific characters used by sed as the delimiter (e.g. "/").
However, escaping any occurrences of the delimiter in the input string would solve the problem.
Consider the below solution of systematically escaping the delimiter character in the input string before having it parsed by sed.
Such escaping can be implemented as a replacement using sed itself, this replacement is safe even if the input string contains the delimiter - this is since the input string is not part of the sed command block:
$ VALUE=$(echo ${VALUE} | sed -e "s#/#\\\/#g")
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345/6
I have converted this to a function to be used by various scripts:
escapeForwardSlashes() {
# Validate parameters
if [ -z "$1" ]
then
echo -e "Error - no parameter specified!"
return 1
fi
# Perform replacement
echo ${1} | sed -e "s#/#\\\/#g"
return 0
}
this line should work for your 3 examples:
sed -r 's#\?(page)=([^&]*)&#/\1/\2#g' a.txt
I used -r to save some escaping .
the line should be generic for your one, two three case. you don't have to do the sub 3 times
test with your example (a.txt):
kent$ echo "?page=one&
?page=two&
?page=three&"|sed -r 's#\?(page)=([^&]*)&#/\1/\2#g'
/page/one
/page/two
/page/three
replace.txt should be
s/?page=/\/page\//g
s/&//g
please see this article
http://netjunky.net/sed-replace-path-with-slash-separators/
Just using | instead of /
Great answer from Anonymous. \ solved my problem when I tried to escape quotes in HTML strings.
So if you use sed to return some HTML templates (on a server), use double backslash instead of single:
var htmlTemplate = "<div style=\\"color:green;\\"></div>";
A simplier alternative is using AWK as on this answer:
awk '$0="prefix"$0' file > new_file
You may use an alternative regex delimiter as a search pattern by backs lashing it:
sed '\,{some_path},d'
For the s command:
sed 's,{some_path},{other_path},'

Escaping single quotes

I want to replace the double quotes in the sed command in the following example with single quotes.
set new_string to do shell script "echo " & quoted form of list_string & " | sed -e 's/$/\"/' -e 's/^/\"/' -e 's/^/+/'"
However if I replace the double quotes with single quotes I get an error, is there a way to escape single quotes?
I'm no sed ninja, so any hints on how to go about this is highly appreciated.
if you want to replace " with ' using sed:
sed 's/"/\x27/g' yourFile
\x27 - single
\x22 - double
it could make code looks cleaner, and with less escape.
see the test:
kent$ cat quote.tmp
""""""
kent$ sed 's/"/\x27/g' quote.tmp
''''''
fYou had a quotation fault. Just to replace double quotes for single quotes, this is enough
set list_string to "This program said: \"Hello World!\""
set new_string to do shell script "/bin/echo -n " & quoted form of list_string & " | sed -e 's/\"/'\\''/g'"
Explaining 's/\"/'\''/g'
The \\ and \" is needed in the applescript environment and will be in the shell just \ and ". So what's entering the shell is 's/"/'\''/g'. Then what's with all the quotes? A very common mistake is thinking that quotations on the command line works the same as in programming. A single quote turns substitution on or off. So the first single quote turns substitution off which mean the next characters will be interpreted as text and has no special meanings (including the escape character). So to escape a single quote we'll need to turn the substitution on, then we can escape a single quote and turn the substitution off again.
You need to be careful about which quotes are being parsed by sed and which are being parsed by the environment invoking sed. Normal invocations of sed come from shell scripts, but (based on your tag) it appears that you're calling it from an AppleScript.
From a shell script you would say
| sed -e 's/$/'\''/' -e 's/^/'\''/' -e 's/^/+/'
But I don't know if sh-style escaping rules are in effect for you or whether you need to additionally escape the \

Escape single quote

The following is working as expected. I want to replace the word "me" with \'
echo "test ' this" | sed 's/'"'"'/me/g'
test me this
Expected result:
test \' this
Is it possible to escape double quotes as well in the same command?
Your question is a little confusing since there's no me in the original string to replace. However, I think I have it. Let me paraphrase:
I have a sed command which can successfully replace a single quote ' with the word me. I want a similar one which can replace it with the character sequence \'.
If that's the case (you just want to escape single quotes), you can use:
pax$ echo "test ' this" | sed "s/'/\\\'/g"
test \' this
By using double quotes around the sed command, you remove the need to worry about embedded single quotes. You do have to then worry about escaping since the shell will absorb one level of escapes so that sed will see:
s/'/\'/g
which will convert ' into \' as desired.
If you want a way to escape both single and double quotes with a single sed, it's probably easiest to provide multiple commands to sed so you can use the alternate quotes:
pax$ echo "Single '" 'and double "'
Single ' and double "
pax$ echo "Single '" 'and double "' | sed -e "s/'/\\\'/g" -e 's/"/\\"/g'
Single \' and double \"
If I've misunderstood your requirements, a few examples might help.
I have some doubts about your question, but anyway maybe my solution is useful for anyone.
Let's me say before all :
\\ that's mean one \ because when you put two together you are cancelling its meaning as metacharacter. And \x27 as single quote, at least for me is easier than working with single a double ...
Finally I put
echo "test me this" | sed 's/me/\\\x27/g'
so here you have test me ==> test \' this
echo "test \' this" | sed 's/\\\x27/me/g'
and here is the opposite.
Is this what you mean?:
# cat <<! | sed 's/["'"'"']/\\&/g'
> quote '
> double quotes "
> quote ' double quotes "
> !
quote \'
double quotes \"
quote \' double quotes \"
Or this:
# echo "test me test"|sed 's/me/\\'"'"'/g'
test \' test
# echo "test me test"|sed 's/me/\\"/g'
test \" test
I find it best to always single quote sed/awk/perl... commands on the command line and make "holes" for double quote parameters used within them.
I needed to use ' in a script to create a dnsmasq config file, this is the technique I used:
echo -e "\toption name *$name*"|sed s/*/\'/g
example output
option name 'GarageDoor'