Replacing special sign with sed in bash - bash

I have a text file and there is a part which I would like to replace with another one. The problem is that the new part contains special signs like {=./} and I'm not able to do that using sed.
What I want to do is to change text123 into {text123=./bla}.
I tried to do it with sed command but look like there are some issues with that. Can any help me with?
Looks like I found a solution but unfortunately there is another problem. I want to put all line below (with all special signs) into text file using echo:
sed -i -e 's/Location/Location\n\n\/\/One_File\nPart Second File '"{ d =.\/source; }"'\nThird File '"{ d =.\/source; }"'/' $file
So once I run script it will take me something like this:
Location
\\One file
Part Second File { d =.\/source; }
Part Third File { d =.\/source; }
Can anyone help me with that? Seems there are too many special signs here, but I need them all.

echo text123 | sed 's/text123/{text123=.\/bla}/g'
result :
{text123=./bla}

Using back reference with sed:
echo text123 | sed 's/\(text123\)/{\1=.\/bla}/g'
{text123=./bla}

Related

Changing a line of text with sed with special characters

The name in the title says it all. However, I'm absolutely the worst with the sed command. So I'm trying to edit the following file:
/var/www/html/phpMyAdmin/config.inc.php
I want to edit the line that says
$cfg['Servers'][$i]['AllowRoot'] = false;
into the following
$cfg['Servers'][$i]['AllowRoot'] = true;
It has so many special characters and whatnot and I have no prior knowledge of how sed works. So here's some commands I've tried to specifically edit that one line.
sed -i "/*.AllowRoot.*/\$cfg['Servers'][\$i]['AllowRoot'] = true;/" /var/www/html/phpMyAdmin/config.inc.php
sed -i "/*.AllowRoot.*/$cfg['Servers'][$i]['AllowRoot'] = true;/" /var/www/html/phpMyAdmin/config.inc.php
# this one finds the line successfully and prints it so I know it's got the right string:
sed -n '/AllowRoot/p' /var/www/html/phpMyAdmin/config.inc.php
sed -i "s/'AllowRoot|false'/'AllowRoot|true'/" /var/www/html/phpMyAdmin/config.inc.php
I have absolutely no idea what I'm doing and I'm not learning a whole lot besides the feeling that the last command splits up 'AllowRoot|false' makes sure that both must be present in the sentence to come back as a result. So to my logic, I thought changing the word false into true would make that happen, but nothing. The other commands return... bizarre results at best, one even emptying the file. Or that's one of the commands I had not written down here, I've lost track after 50 attempts. What is the solution here?
The [ and ] need to be escaped to match literal brackets, instead of inadvertently starting a bracket expression. This should work:
$ sed -i "/\$cfg\['Servers'\]\[\$i\]\['AllowRoot'\]/s/false/true/" /var/www/html/phpMyAdmin/config.inc.php
There is not many things to escape in sed. Main problem in your line is / which you have chosen as delimiter (most common, but not required). I suggest you use # and the following will work:
sed -i "s#$cfg['Servers'][$i]['AllowRoot'] = false;<br />#$cfg['Servers'][$i]['AllowRoot'] = true;<br />#g" input.txt
however you need to think about bash interpreter as well. $i and $cfg will be interpreted as variables. My suggestion is that when you want to match a string like this to put the sed expression in a text file like this:
cat allow_root_true.sed
s#['Servers'][]['AllowRoot'] = false;<br />#['Servers'][]['AllowRoot'] = true;<br />#g
and run the command using sed -f like this:
sed -i -f allow_root_true.sed input.txt
Warning -i will change the input file
sed can't do literal string matching which is why you need to escape so many characters (see Is it possible to escape regex metacharacters reliably with sed), but awk can:
$ awk -v str="\$cfg['Servers'][\$i]['AllowRoot']" 'index($0,str){sub(/false/,"true")} 1' file
//some text here
$cfg['Servers'][$i]['AllowRoot'] = true;<br />
//some more text here
Run code snippetHide resultsExpand snippet
In the above we only have to escape the $s to protect them from the shell since the string is enclosed in "s to allow it to include 's.

Appending text to specific patterns in a fasta BASH

I have a fasta with headers like this:
tr|Q7MX99|Q7MX99_PORGI_BACT
I would like them to say:
tr|Q7MX99|Q7MX99_PORGI_BACT_ORALMICROBIOME
So basically, whenever I have PORGI_BACT I want to append _ORALMICROBIOME to each instance.
I'm sure there is an easy fix through the terminal, but I can't seem to find it.
My first idea is to do something like:
sed 's/>.*/&_ORALMICROBIOME/' file.fa > outfile.fa
BUT I only want to add to specific header endings, and that is where I'm stuck.
Using sed:
sed -r 's/(^.*)(PORGI_BACT|HUMAN_MAM|TESTA_BACT)(.*$)/\1\2_ORALMICROBIOME\3/' file.fa > outfile.fa
Enable regular expression interpretation using -r or -E and then split the line into three sections based on "PORGI_BACT" being in section two and then substitute the line for the first and second sections, followed by "_ORALMICROBIOME" and finally the third section.
You are almost close. Would you please try the following:
sed 's/^>.*PORGI_BACT/&_ORALMICROBIOME/' file.fa > outfile.fa
[Edit]
According to the OP's requirement, how about:
sed -E 's/^>.*(PORGI_BACT|HUMAN_MAM|TESTA_BACT)/&_ORALMICROBIOME/' file.fa > outfile.fa
Sample input as file.fa:
>SEQ0|tr|Q7MX99|Q7MX99_PORGI_BACT
FQTWEEFSRAAEKLYLADPMKVRVVLKYRHVDGNLCIKVTDDLVCLVYRTDQAQDVKKIEKF
>SEQ1|tr|Q7MX88|Q7MX88_HUMAN_MAM
KYRTWEEFTRAAEKLYQADPMKVRVVLKYRHCDGNLCIKVTDDVVCLLYRTDQAQDVKKIEKFHSQLMRLME
LKVTDNKECLKFKTDQAQEAKKMEKLNNIFFTLM
>SEQ2|tr|Q7MX77|Q7MX77_TESTA_BACT
EEYQTWEEFARAAEKLYLTDPMKVRVVLKYRHCDGNLCMKVTDDAVCLQYKTDQAQDVKKVEKLHGK
>SEQ3|tr|Q7MX66|Q7MX66_DUMMY
MYQVWEEFSRAVEKLYLTDPMKVRVVLKYRHCDGNLCIKVTDNSVCLQYKTDQAQDVK
Output:
>SEQ0|tr|Q7MX99|Q7MX99_PORGI_BACT_ORALMICROBIOME
FQTWEEFSRAAEKLYLADPMKVRVVLKYRHVDGNLCIKVTDDLVCLVYRTDQAQDVKKIEKF
>SEQ1|tr|Q7MX88|Q7MX88_HUMAN_MAM_ORALMICROBIOME
KYRTWEEFTRAAEKLYQADPMKVRVVLKYRHCDGNLCIKVTDDVVCLLYRTDQAQDVKKIEKFHSQLMRLME
LKVTDNKECLKFKTDQAQEAKKMEKLNNIFFTLM
>SEQ2|tr|Q7MX77|Q7MX77_TESTA_BACT_ORALMICROBIOME
EEYQTWEEFARAAEKLYLTDPMKVRVVLKYRHCDGNLCMKVTDDAVCLQYKTDQAQDVKKVEKLHGK
>SEQ3|tr|Q7MX66|Q7MX66_DUMMY
MYQVWEEFSRAVEKLYLTDPMKVRVVLKYRHCDGNLCIKVTDNSVCLQYKTDQAQDVK

Is there a way to add text to the end of a string in a conf file in linux?

I have a problem: I have a file that, if I knew how, I would like to edit from the command. I would like to locate the file by content on that line.
I am in CyberPatriot, and my team is second in my state. I know someone who is on the number one team and I know one of the people on the first team. It kills me so I want to make a list of commands that I can go off of to make it faster and more efficient.
Imagine I had this file:
example
oof
goo
random
yes
and I wanted to change it to this:
example
oof
goo
random 'added text'
yes
How do I do so?
I know I can use the echo command to add text to the end of a file, but I don't know how to add text to the end of a specific line.
Thanks, Owen
You can use sed for this purpose.
sed 's/random/& Hello World/' file
to append text to the matched string.
You can use ^random$ to make sure the entire line is matched, before appending.
If you need to modify the file directly, you can use the -i flag, which facilitates in-place editing. Further, using -i.bak creates a backup of the original file first before modifying it, as in
sed -i.bak 's/random/& Hello World/' file
The original copy of the file can be found in file.bak
More about sed : https://www.gnu.org/software/sed/manual/sed.html
Use something like below
sed '4!d' file | xargs -I{} sed -i "4s/{}/{} \'added text\'/" file
Basically in the above command, we are getting the 4th line of the file using sed sed '4!d' file and then using this line to replace it with the same text and some new text(added text)

Prepend, copy/paste, and append using sed?

I have a file full of IDs which I need to use to build a list of URLs as part of a bash file.
ids.txt is as follows:
s_Foo
p_Bar
s1_Blah
e_Yah
The URLs will always end in a filename that contains the ID, in its own path.
I've looked around for how to prepend and append using sed, but cannot figure out to do the duplicating copy/paste part (\1) using that tool. The ID can be anything, so pattern matching seems hard. Duplication of everything before the line break seems more sensible? I don't know.
How do I create something like this as urls.txt using sed or awk? Is it possible?
https://link.domain.com/list/s_Foo/s_Foo_meta.xml
https://link.domain.com/list/p_Bar/p_Bar_meta.xml
https://link.domain.com/list/s1_Blah/s1_Blah_meta.xml
https://link.domain.com/list/e_Yah/e_Yah_meta.xml
$ sed 's#.*#https://link.domain.com/list/&/&_meta.xml#' ids.txt
https://link.domain.com/list/s_Foo/s_Foo_meta.xml
https://link.domain.com/list/p_Bar/p_Bar_meta.xml
https://link.domain.com/list/s1_Blah/s1_Blah_meta.xml
https://link.domain.com/list/e_Yah/e_Yah_meta.xml
$ awk '{sub(/.*/,"https://link.domain.com/list/&/&_meta.xml")}1' ids.txt
https://link.domain.com/list/s_Foo/s_Foo_meta.xml
https://link.domain.com/list/p_Bar/p_Bar_meta.xml
https://link.domain.com/list/s1_Blah/s1_Blah_meta.xml
https://link.domain.com/list/e_Yah/e_Yah_meta.xml
try gnu sed:
sed -E 's/\S+/https://link.domain.com/list/&/&_meta.xml' ids.txt >urls.txt

Shell Removing part of a string with sed

Good day.
I actually have 2 questions that are related to the sed command in shell and they are very similar.
The first question is how to use sed to get a file name and remover part of it's name like the example below:
Original file:
BAT_MAN_T_spades_proc_whatever_t6_12345_14785963214785_12345.txt
What i want the file name to look like:
BAT_T_spades_proc_whatever_t6_12345_14785963214785_12345.txt
I just want the "MAN" part after the first underline to be removed out of the original file name.
The second question is about the following sed command that I've found on a file a while ago:
random_string_var_name=$(echo $file_name | sed -r 's/^[^_]*_[^_]*_(.*_t[0-9]{1}).*(_[0-9]*)\.txt/_\1\2/')
this pretty much get parts of a file name a saves it on a variable, like the example bellow:
Name of the file:
BAT_MAN_T_spades_proc_whatever_t6_12345_14785963214785_12345.txt
What that sed command gets:
T_spades_proc_whatever_t6_12345
I got what it does but i don't understand how that command works, so i would like to understand that.
I just want the "MAN" part after the first underline to be removed out of the original file name.
echo "BAT_MAN_T_spades_proc_whatever_t6_12345_14785963214785_12345.txt" | sed "s/MAN_//"
What if i want to always remove the first word after the first underline and keep everything else?
echo "BAT_MAN_T_spades_proc_whatever_t6_12345_14785963214785_12345.txt" | sed -r 's/^([^_]*)_[^_]*(_.*)/\1\2/'
what does this do: echo $file_name | sed -r 's/^[^_]*_[^_]*_(.*_t[0-9]{1}).*(_[0-9]*)\.txt/_\1\2/')
-r: runs sed in "extended regex" mode
^: matches beginning of word
[^_]* matches everything except underline 0 or more times
_ matches underline
(.*_t[0-9]{1}) matches zero or more of anything followed by _t and only one number. This match is stored in variable 1
(_[0-9]*) same thing, only that there is no prefix
/_\1\2: replaces the whole filename with _ at the beginning and the match in the first brackets and the match in the second bracket
I recommend reading up on regular expressions. They are important and not really hard to get into
I think that you may have something else than "MAN", you may have "WOMAN". So you can use:
file_name=BAT_WOMAN_T_spades_proc_whatever_t6_12345_14785963214785_12345.txt
echo $file_name | sed 's/_[^_]*_/_/'

Resources