How to match double quotes using sed - unix

How can I make sed use double quotes (") as a match?
I try to replace "source/design to "source/design_new only without changing the second coding.
Input:
"source/design",
"include/source/design",
Expect Output:
"source/design_new", #only this line renaming
"include/source/design"
I tried with command:
sed "s/\"source\/design/\"source\/design_new/g"
but it is complaining with an unmatched " error. Is there any way to use double quotes in sed?

Basically, sed takes whatever follows the s as the separator (except newline or backslash). So you can use some any other character - let's say ; - as a separator instead of /.
Example:
sed 's;"source/design;"source/design_new;g' input_file

Just use single quotes around the command instead of double quotes. This way you do not have to worry about how to handle them:
sed 's~"source/design~"source/design_new~g' file
^ ^
With your given input this command returns:
"source/design_new",
"include/source/design",
Also note you can avoid escaping every / by using another separator in sed (I used ~, although it could also be | or another one).

Welcome to tcsh. You can't include double quotes in doublequotes. End the double quotes and backslash the double quote:
sed "s/"\""source\/design/"\""source\/design_new/g"
Or, more readable (using a different separator to avoid the need to backslash slashes, and using no quotes as they're not needed for letters, slashes and underscores:
sed s=\"source/design=\"source/design_new=g

Related

Find and replace: \'

I'm trying to replace a every reference of \' with ' in a file
I've used variations of: sed -e s/\'/"\'"/g file.txt
But they always replace every.single.(single).quote
Any help would be greatly appreciated.
Not sure it's the best solution,I could do it like this:
sed "s/[\]'/\"\'\"/g" file.txt
(putting the backslash character in a character range so it doesn't interfere with the following quote, and protect with double quotes)
Or just extending your syntax, without quotes but using almost the same trick:
sed -e s/[\\]\'/"\'"/g file.txt
An approach trying to conserve as much of the "single-quotedness" of the sed command as possible:
sed 's/\\'"'"'/\'/g'
Just escaping \ with \\ and getting a single quote into the command with '"'"': the first single quote ends the command so far, then we have a double-quoted single quote ("'"), and finally an opening single quote for the rest of the command.
Alternatively, double quoting the whole command and escaping both the backslash and single quote:
sed "s/\\\'/\'/g"
The correct syntax is:
$ echo "foo'bar" | sed 's/'\''/\'/'
foo'bar
Every script (sed, awk, whatever) should always be enclosed in single quotes and you just us other single quotes to stop/restart the script delimiters break out to shell for the minimal portion of the script that's absolutely necessary, in this case long enough to use \'. You need to break out to shell to specify that ' because per shell rules no script enclosed in 's can contain a ', not even if you try to escape it.
echo "foo'bar" | gawk '{gsub(/\47/,"\\'")}1'
foo'bar
The tricky part here is to replace a single quote with ampersand.
First in order to make the single quote manageable use its octal
code here \47 and then escaping ampersand by two back slash. And all of sudden
it becomes feasible :)

sed: remove digits after word

I have a simple sed question.
I have data like this:
2600,Sale,"Approved 911973",244.72
2601,Sale,"Approved 04735C",490.51
2602,Sale,"Approved 581068",52.82
2603,Sale,"Approved 009275",88.10
How do I make it like this:
2600,Sale,Approved,244.72
2601,Sale,Approved,490.51
2602,Sale,Approved,52.82
2603,Sale,Approved,88.10
Notice the numbers after approved are gone as well as the quotes. I can remove quotes with:
sed 's/,$//gn' file
but I don't know how to remove the spaces and digits.
Thanks!
sed "s/\"Approved[^,]*/Approved/g"
It finds the quoted "Approved" followed by any non-comma character, up until the first comma encountered, and replaces it with Approved (no quotes)
2600,Sale,Approved,244.72
2601,Sale,Approved,490.51
2602,Sale,Approved,52.82
2603,Sale,Approved,88.10
Using extended regex with sed:
sed -r 's/"([^[:space:]]*)[^"]*"/\1/g' file
The above regex targets for any quoted string. If you want to target the string Approved, then:
sed -r 's/"(Approved)[^"]*"/\1/g' file
With basic regex:
sed 's/"\(Approved\)[^"]*"/\1/g' file
To target any quoted string, change Approved to [^[:space:]]*
One way using awk(only if the other columns does not contain multiple words as in your sample):
awk -F"[ ,]" '{gsub("\"","");$1=$1}1' OFS=, file
awk -F'[," ]' '{OFS=","; print $1,$2,$4,$7}' file
Output:
2600,Sale,Approved,244.72
2601,Sale,Approved,490.51
2602,Sale,Approved,52.82
2603,Sale,Approved,88.10
I suppose there is no other whitespace.

SED character after the substitute command ("s")

I know about s// type command in sed, however never saw using s#. Could someone explain what exactly this is doing?
% sed -e "s#SRC_DIR=.*#SRC_DIR=$PROJECT_SRC_DIR#g" -i proj.cfg
I understand that -e defines a script to execute, and the script is withing "", but what exactly s# does?
Checked http://www.grymoire.com/Unix/Sed.html and gnu website, but no luck.
# is a sed delimiter like /. We could use ~, #, /, ;, etc as sed delimiters. They uses a different delimiter # because they don't want to escape / slashes. If you use # as delimiter, you don't need to escape / forward slash. But if you use / as delimiter, you must need to escape / as \/ or otherwise sed would consider / as delimiter.
From sed's manual:
The syntax of the s (as in substitute) command is ‘s/regexp/replacement/flags’. The / characters may be uniformly replaced by any other single character within any given s command. The / character (or whatever other character is used in its stead) can appear in the regexp or replacement only if it is preceded by a \ character.

Using sed to replace text with curly braces

I am trying to find the following text
get_pins {
and replace it with
get_pins -hierarchical {proc_top_*/
I've tried using sed but I'm not sure what I'm doing wrong. I know that you need # in front of curly braces but I still can't get the command to work properly.
The closest I've come is to this:
sed 's/get_pins #{#/get_pins -hierarchical #{#proc_top_*\//g' filename.txt > output
but it doesn't do the replacement I wanted above.
#merlin2011's answer shows you how to do it with alternative delimiters, but as for why your command didn't work:
It's actually perfectly fine, if you just remove all # chars. from your statement:
sed 's/get_pins {/get_pins -hierarchical {proc_top_*\//'g filename.txt > output
There are two distinct escaping requirements involved here:
Escaping literal use of the regex delimiter: this is what you did correctly, by escaping the / as \/.
Escaping characters with special meaning inside a regex in general: this escaping is always done with \-prefixing, but in your case there is NO need for such escaping: since you're NOT using -E or -r to indicate use of extended regexes - and are therefore using a basic regex - { is actually NOT a special character, so you need NOT escape it. If, by contrast, you had used -E (-r), then you should have escaped { as \{.
The problem is not in the curly braces, it's in the /.
This is exactly why sed lets you do alternate delimiters.
The line below uses ! as a delimiter instead, and works correctly for a simple file with get_pins { in it.
sed 's!get_pins {!get_pins -hierarchical {proc_top_*/!g' Input.txt
Output:
get_pins -hierarchical {proc_top_*/
Update: Based mklement0's comment, and testing with the csh shell, the following should work in csh.
sed 's#get_pins {#get_pins -hierarchical {proc_top_*/#g' Input.txt
This awk should do the replace:
awk '{sub(/get_pins {/,"get_pins -hierarchical {proc_top_*/")}1'

Sed replace only exact match

I wan't to replace a string like Europe12 with Europe12_yesturday in a file. Without changing the Europe12-36 strings that also exists in the file.
I tried:
$basename=Europe12
sed -i 's/\b$basename\b/${basename}_yesterday/g' file.txt
but this also changed the Europe12-36 strings.
Require a space or end of line character:
sed 's/Europe12\([ ]|$\)/Europe12_yesturday\1/g' input
Manually construct the delimiter list you want instead of using \b, \W or \<. - is not part of the word characters (alphanumericals), so that's why this also matches your other string. So try something like this, expanding the list as needed: [-a-zA-Z0-9].
You can do it in 2 times:
sed -e 's/Europe12/Europe12_yesturday/g' -e 's/Europe12_yesturday-36/Europe12-36/g' file.txt
sed 's/\(Europe12[[:blank:]]\)/\1_yesturday/g;s/Europe12$/&_yesturday/' YourFile
[[:blank:]] could be completeted with any boundary you accept also like .,;:/]) etc (be carrefull of regex meaning of this char in this case)
It is little late to reply..
It can be achieved easily by "word boundary" notation (\<..\>)
sed -i 's/\<$basename\>/${basename}_yesterday/g' file.txt

Resources