This question already has answers here:
Using different delimiters in sed commands and range addresses
(3 answers)
Closed 5 years ago.
I want to replace "1/1" with "1/2" in all files in a directory
I tried
find . -type f -exec sed -i 's/1/1/1/2/g' {} +
and got
sed: -e expression #1, char 6: unknown option to `s'
what am i doing wrong?
how to use this when i need replace it with pattern containing "/"?
Thanks in advance
The substitute(s) command have forward slashes that delimits it. Its format is :
s/pattern/replacement/flag
The real question here is how you would tackle the forward slashes which appear in your pattern. You can escape the forward slashes in your pattern
which is the dirty way to do it.
Fortunately sed allows different delims for s command So you could do something like
find . -type f -exec sed -i 's#1/1#1/2#g' {} \;
Here note the use of # as the delim for s which helps you avoid an influx of backslashes in your substitution.
Related
This question already has answers here:
How to insert strings containing slashes with sed? [duplicate]
(11 answers)
Closed 5 years ago.
I have a directory's tree with several files inside.
I want to replace in every file, the string index.html for a character /.
Since / is a special character, How can I instruct to the linux "sed" command so I can change all files that I have under a directory?
Thanks!
Sed is usualy used with / as a separator. Actually you can use any symbol as a separator, sed just uses the first symbol after s command for that. For example sed 's|/|slash|'. Or you can escape / like that sed s/\//slash/. It's dangerous command, be careful, make a backup of your dir:
for file in `find /your/dir/ -type f`; do sed -i "$file" 's|index.html|/|g'; done
This question already has an answer here:
sed fails with "unknown option to `s'" error [closed]
(1 answer)
Closed 7 years ago.
I'm trying to use sed to update a config file using a bash script. I have a similar sed command right above this one in the script that runs fine. I can't seem to figure out why this is breaking:
sed -i.bak \
-e s/"socketPath:'https://localhost:9091'"/"socketPath:'/socket'"/g \
$WEB_CONF
Any ideas?
The quotes and double quotes are causing problems.
You are using them in view of the slashes in the string.
In sed you can use another delimiter, such as a #.
sed -e 's#socketPath:https://localhost:9091#socketPath:/socket#g' \
$WEB_CONF
Escape your slashes in the pattern or use a different delimiter like this:
sed -i.bak \
-e s%"socketPath:'https://localhost:9091'"%"socketPath:'/socket'"%g \
$WEB_CONF
I am confused looking at the delimiters you have used so you can't blame sed for goofing up. When your dataset has / in them, it is often advised to use a different delimiters like # or _ (yes, sed supports various delimiters).
Also, your quoting looks abit off. The syntax should be:
sed -i.bak 's#substitute#replacement#g' "$WEB_CONF"
If your substitute and/or replacement has variables use " instead ' which will allow it to interpolate.
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},'
I am trying to use unix sed command to find line numbers that match a particular regular expression. The pattern of my file is below
A<20 spaces>
<something>
<something>
..
..
A<20 spaces>
<soemthing>
<something>
I need all the line numbers of A<20 spaces>
I used sed -n '/A[ ]{20}/'= <file_name> but it does not work. If I manually type in twenty spaces it does work.
Can some one please tweak the above command to make it work.
The braces in the expression need to be escaped with backslashes:
% sed -n '/A[ ]\{20\}/=' test.txt
1
6
An alternative would be to use -E to interpret regular expressions as extended (modern) regular expressions:
% sed -nE '/A[ ]{20}/=' test.txt
1
6
Or potentially use grep instead, which takes fewer characters to specify the same search:
% grep -n 'A[ ]\{20\}' test.txt
The correct syntax would be /A \{20\}/ (and I'm failing to understand where you got your syntax from).
edit: repeat a space, not an A. not my day
use the -E or the -r switch for extended regexp
just to be sur of the content request is answered because it literraly mean "20 spaces" and not Twenty " " char that everyone understand due to the sed line sample failing (i guess this the good one so other reply are fine in this case)
sed -n "/<20 spaces>/ =" file_name
This question already has answers here:
Using different delimiters in sed commands and range addresses
(3 answers)
Closed 1 year ago.
I'm writing a shell script with this command:
sed -e 's/OLD_ITEM/NEW_ITEM/g'
But I actually want to do something that includes a directory:
sed -e 's/FOLDER/OLD_ITEM/NEW_ITEM/g'
How do ignore the forward slash so that the entire line FOLDER/OLD_ITEM is read properly?
You don't have to use / as delimiter in sed regexps. You can use whatever character you like, as long as it doesn't appear in the regexp itself:
sed -e 's#FOLDER/OLD_ITEM#NEW_ITEM#g'
or
sed -e 's|FOLDER/OLD_ITEM|NEW_ITEM|g'
You need to escape the / as \/.
The escape (\) preceding a character tells the shell to interpret that character literally.
So use FOLDER\/OLD_ITEM
Escape it !
sed -e 's/FOLDER\/OLD_ITEM/NEW_ITEM/g'