replace a word with string in a file using shell - linux

I have a file in which I have to convert the string "lock allpages" into STRING
" LOCATION 'hdfs://LOCATION/DIRECTORY/TBL;' " . I tried sed but it's throwing some error. can someone suggest the changes that I need to do. I tried below but it's not working. and also can someone suggest how to use sed for replacing multiple strings at once
sed -i 's/lock allpages/LOCATION 'hdfs://LOCATION/DIRECTORY/TBL';'

You need to escape your single quotes and forward slashes in your sed statement. .. That and you're not COMPLETING the sed statement .. You need to close your second argument with a slash -> / (Or whatever delimiter you choose)
sed -i 's/lock allpages/LOCATION \'hdfs:\/\/LOCATION\/DIRECTORY\/TBL;\'/g'
OR if you put the statement in double quotes . There's no need to escape the single quotes
sed -i "s/lock allpages/LOCATION 'hdfs:\/\/LOCATION\/DIRECTORY\/TBL;'/g"
FURTHER -- If you used a different delimiter .. Like a pipe | -- There would be no need for escaping at all...
sed -i "s|lock allpages|LOCATION 'hdfs://LOCATION/DIRECTORY/TBL;'|g"

Related

remove backslash only from quote character using sed

I have string: this is a [\"sample\"] sample\'s.
What would be the correct way to remove backslashes from the double quote, preserving the double quote.
Expected output: this is a ["sample"] sample\'s.
I've tested: sed -i 's/\\\"//g' file.txt which is removing the "
Your command is almost correct. You just forgot to substitute with a double quote:
sed -i 's/\\"/"/g' file.txt
sed's s command substitutes the first part (between / here) with the second part. The g flag repeats the operation throughout the line. Your mistake was that the second part was empty, thus effectively deleting the whole \" string.
BTW, escaping the double quote is not necessary since your sed command is inside single quotes.

How to escape certain characters for sed? [duplicate]

This question already has answers here:
What special characters must be escaped in regular expressions?
(13 answers)
Closed 2 years ago.
I want to remove a line from a file and understand this can be done with sed.
The command below fails because of unterminated address regex
sed -i '/$settings['file_temp_path'] = '../tmp';/d' file.php
Having read the the answer at unterminated address regex while using sed . I now understand this is because characters [ and / must be escaped.
Having tried this, the code below is still unsuccessful
sed -i '/$settings\['file_temp_path'] = '..\/tmp';/d' file.php
What is wrong with this? What am I missing?
This might work for you (GNU sed):
sed -i '\#\$settings\['\''file_temp_path'\''\] = '\''\.\./tmp'\'';#d' file
When the regexp/replacement contains the match delimiter (usually /), it can either be escaped/quoted or the delimiters can be altered i.e. /\/tmp/ or \#/tmp#. Note that in the case of the substitution command s/\/tmp/replacement/ can also be s#/tmp#replacement# and leading delimiter does not need to escaped/quoted.
Meta characters i.e. ^,$,[,],*,.,\ and & must be escaped/quoted by \or placed in a character class e.g. . should be \. or [.].
As a rule of thumb, sed commands should be enclosed in single quotes ' and for single quotes to be included in the regexp they should be replaced by '\'' which closes off the existing commands, shell escapes/quotes a ' and reopens the next sed command.
Using double quotes " may also be used but may have unexpected side effects as they are open to shell interpolation.
N.B. If the regexp/substitution delimiter is put inside a character class it does not need to be escaped/quoted i.e. if / is the delimiter then [/] is the same as \/. Also note, that {,},|,? and + should not be escaped/quoted if they are to represent their literal value unless the -E or -r sed command line option is invoked, in which case they should be i.e + represents the plus sign as does \+ when the -E is invoked, whereas \+ and + when the -E or -r is invoked represent one or more of the preceding character/group.
You need to escape several special characters in your pattern, including $.
Example content of file.php:
foo
$settings['file_temp_path'] = '../tmp';
bar
Example code:
$ sed -i "s/\$settings\['file_temp_path'\] = '..\/tmp';//" file.php
$ cat file.php
foo
bar

How to correctly detect and replace apostrophe (') with sed?

I'm having a directory with many files having special characters and spaces. I want to perform an operation with all these files so I'm trying to store all filenames in a list.txt and then run the command with this list.
The special characters in my list are & []'.
So basically I want to use sed to replace each occurence with \ + the character in question.
E.g. : filename .txt => filename\ .txt etc...
The thing is I have trouble handling apostrophes.
Here is my command as of now :
ls | sed 's/\ /\\ /g' | sed 's/\&/\\&/g' | sed "s/\'/\\'/g" | sed 's/\[/\\[/g' | sed 's/\]/\\]/g'
At first I had issues with, I believe, the apostrophes in the string command in conflict with the apostrophes surrounding the string. So I used double quotes instead, but it still doesn't work.
I've tried all these and nothing worked :
sed "s/\'/\\'/g" (escaping the apostrophe)
sed "s/'/\'/g" (escaping nothing)
sed "s/'/\\'/g" (escaping the backslash)
sed 's/"'"/\"'"/g' (double quoting single quote)
As a disclaimer, I must say, I'm completely new to sed. I just run my first sed command today, so maybe I'm doing something wrong I didn't realize.
PS : I've seen those thread, but no answer worked for me :
https://unix.stackexchange.com/questions/157076/how-to-remove-the-apostrophe-and-delete-the-space
How to replace to apostrophe ' inside a file using SED
This may do:
cat file
avbadf
test&rr
more [ yes
this ]
and'df
sed -r 's/(\x27|&|\[|\])/\\\1/g' file
avbadf
test\&rr
more \[ yes
this \]
and\'df
\x27 is equal to singe quote '
\x22 is equal to double quote "
Whoops, I found the answer to my question. Here is the working input :
sed "s/'/\\\'/g"
This will effectively replace any ' with \'.
However I'm having trouble understanding exactly what's happening here.
So if I understand correctly, we are escaping the backslash and the apostrophe in the replacement string. Now, if somebody could answer some those, I would be grateful :
Why don't we need to escape the first quote (the one in the pattern to find) ?
Why do we have to escape the backslash whereas for the other characters, there's no need ?
Why do we need to escape the second quote (the one in the replacement string) ?
I think all of your sed matches actually need that replacement pattern. This one seems to work for all examples:
ls | sed "s/\ /\\\ /g" | sed "s/\&/\\\&/g" | sed "s/\[/\\\[/g" | sed "s/\]/\\\]/g" | sed "s/'/\\\'/g"
So it is s/regex/replacement/command and 'regex' and 'replacement' have different sets of special characters.
The only one that's different is s/'/\\\'/g and there only because I don't believe there is any special ' character on the regex expression. There is some obscure \' special character in the replacement expression, for matching buffer ends in multi-line mode, accord to the docs. That might be why it needs an escape in the replacement side, but not in the regex side.
For example, \5 is a special character in the replacement expression, so to replace:
filename5.txt -> filename\5.txt
You would also need, as with apostrophe:
sed "s/5/\\\5/g"
It probably has to do with the mysterious inner works of sed parsing, it might read from right to left or something.
Please try the following:
sed 's/[][ &'\'']/\\&/g' file
By using the same example by #Jotne, the result will be:
gavbadf
gtest\&rr
gmore\ \[\ yes
gthis\ \]
gand\'df
[How it works]
The regex part in the sed s command above just defines a character
class of & []', which should be escaped with a backslash.
The right square bracket ] does not need escaping when put
immediately after the left square bracket [.
The obfuscating part will be the handling of a single quote.
We cannot put a single quote within single quotes even if we escape it.
The workaround is as follows: Say we have an assignment str='aaabbb'.
To put a single quote between "aaa" and "bbb", we can say as
str='aaa'\''bbb'.
It may look puzzling but it just concatenates the three sequences;
1) to close the single-quoted string as 'aaa'.
2) to put a single quote with an escaping backslash as \'.
3) to restart the single-quoted string as 'bbb'.
Hope this helps.

Replace a string using sed

I want to replace a string ip_ttl="1" with ip_ttl="2" using sed.
I've tried sed -i "s/ip_ttl="1"/ip_ttl="2"/g" - but its not working.
Please help!
Put your sed code inside single quotes, because your code already contains double quotes.
sed -i 's/ip_ttl="1"/ip_ttl="2"/g' file
If you put your code within two double quotes, sed would terminate the program once another double quote was reached. So " before 1 was reached, it would consider as the end and terminates the program.
Update:
If the number always changes then it's better to define the pattern which matches any number.
sed -i 's/ip_ttl="[0-9]\+"/ip_ttl="2"/g' file
If you are using quotation marks in your pattern either escape double quotes in pattern:
sed -i "s/ip_ttl=\"1\"/ip_ttl=\"2\"/g"
or enclose whole pattern in single quotes:
sed -i 's/ip_ttl="1"/ip_ttl="2"/g'
Alternatively you can escape the quotation marks
sed -i "s/ip_ttl=\"1\"/ip_ttl=\"2\"/g" file
Sometimes that's useful because you have both single and double quotes in a string you're selecting for.

search and replace string using sed

i have a sed command like this for search and replace string inside a file:
sed -i -e 's/`db1`./`db2`./g' result/files1.sql
that is working fine to replace the db1 to db2 inside the file of: result/files1.sql
however when i change it to bash and variable format, it does not work.
sed -i -e "s/`${mydbname}`./`${mydbname2}`./g" "${mypath}"
i get error like:
./mycoolscript: line 241: db1: command not found
./mycoolscript: line 241: db2: command not found
any solution would be great.
If is something you need to replace, you will need to escape by . Here it is
sed -i -e "s/\`${mydbname}\`./\`${mydbname2}\`./g" "${mypath}"
Escape the backtick character
sed -i -e "s/\`${mydbname}\`./\`${mydbname2}\`./g" "${mypath}"
Bash treats the part within backticks as a command and first executes that.
Try this
sed -i -e "s/${mydbname}/${mydbname2}/g" "${mypath}"
There is one more way, of using single quotes for literals & double quotes only around variables/escape sequences.
sed -i -e 's/`'"${mydbname}"'`./`'"${mydbname2}"'`./g' "${mypath}"
Because of single quotes, you will not have to escape the special characters.
The trade-off between escaping special characters vs. using mix of single & double quotes would depend on number of special characters vs. number of variables.
If there are too many characters that would need escaping & less number of variables, I would prefer mix of single & double quotes.

Resources