Find variable word and replace it in file using Bash [duplicate] - bash

This question already has answers here:
Replace a string in shell script using a variable
(12 answers)
Closed 5 years ago.
I have a file and from this file I am trying to find a word and replace it with another word using Bash. I am using sed to do this and please note that the word that I am looking for is an output from a command. So I am trying to find a word, which is the output of a command, and replace it with another word and override the previous word.
This is my code:
File=file.txt
File2=file2.txt
min=$(cat $File2 | grep word);
sed -i 's/$min/max/g' $File
It's not producing any error, but I am unable to find the word in order to replace it. When I manually type the word rather than using the variable "$min" it works just fine. So when I do this, it works:
sed -i 's/min/max/g' $File
but when I do this, it doesn't:
sed -i 's/$min/max/g' $File
I am thinking maybe sed doesn't accept variables as a search string. Any idea how I can achieve this?
thank you.

Use double quotes for the sed expression, this should work:
sed -i "s/$min/max/g" $File

Related

Replace a string with special characters using sed [duplicate]

This question already has answers here:
Is it possible to escape regex metacharacters reliably with sed
(4 answers)
Closed 7 months ago.
I have the below string
sec.val.hos.patn=.*app\.com$|localhost$|127\.0\.0\.1$
I want replace .*app\.com$|localhost$|127\.0\.0\.1$ with * so that final string looks like below
sec.val.hos.patn=*
I am trying to solve this problem using below sed command on Mac OS
sed -i ' ' 's~\.\*app\\\.com\$\|localhost\$\|127\\\.0\\\.0\\\.1\$~\*~g' file.txt
but unable to get the desired replacement. Can someone please help me to get this working.
I don't know if the pattern is actually more complex than you sample, but seems this should do the trick:
sed 's/\(^.*=\).*$/\1*/' <<< "sec.val.hos.patn=.*app\.com$|localhost$|127\.0\.0\.1$"
Here we capture everything from the start to =, then we replace the whole thing with capture group 1 plus *.

How to remove a line from a file containing certain pattern value in variable? [duplicate]

This question already has answers here:
How to use variables in a command in sed?
(4 answers)
Closed 4 years ago.
I have a file that contains names of directories and some other information, but the names always come first.The file looks like this:
/home/user/Desktop/IS/proj_1/sch/text 4 2018-03-14 07:41:01
/home/user/Desktop/IS/file1.txt 3 2018-03-14 16:50:01
...
I have a variable "name" that contains this for example:
/home/user/Desktop/IS/file1.txt
And I need to delete that one particular line from the file somehow. I've searched many posts and tried using various quotations and ways of expansions, but nothing did the trick. If I type it in directly, it deletes the line without problem, but I'm having a hard time doing it from a variable. This is what I came up with but it still doesn't work.
sed -i '/"$name"/d' $File_name
Try this :
sed -i "\|$name|d" "$File_name"
As you can see, I changed the delimiter for |, you can pick another one depending of your needs from most of ascii characters (not all works)
sed command doesn't allow plain string based search and performs search using only a regex (BRE or ERE). That requires escaping all special regex meta-characters in search pattern.
Better to use a non-regex approach using awk:
name='/home/user/Desktop/IS/file1.txt'
awk -v p="$name" '!index($0, p)' file
/home/user/Desktop/IS/proj_1/sch/text 4 2018-03-14 07:41:01
Whatever given in single quotes wont get expanded.
Try:
sed -i "/$name/d" $File_name
If you have problems with /, escape them properly.
name=$(echo "$name"|sed -e "s/\//\\\\\//g")
sed -i "/$name/d" $File_name

How to scrape end of line in grep? [duplicate]

This question already has answers here:
How to find patterns across multiple lines using grep?
(28 answers)
Closed 6 years ago.
I have a file that contains a sequence already broken into lines, something like this:
CGCCCATGGGTCGTATACGTAATGGGAAAACAAAGCATGGTGTAACTATGGTAAGTGCTA
GACAATACAAGAAGGCTGATATTTGTAGAATAATTCATTTGAATTATTATGCTGTAAATA
GCTAGATTATTATGCATAATTACTTTGAGAGGTGATCAATCAATTCGACCCTTGCCAATT
I want to search a specific pattern in this file like GCTGTAAATAGCTAGATTA for example.
The problem is that the pattern may be cut by a newline at an unpredictable place.
I can use :
grep -e "pattern" file
but it cannot avoid "new line" character and doesn't give the result. How can I modify my command to ignore \n in my search?
Edit:
I don't know either my query exists in the file or not, and if it is there, I don't know where it exists.
The best solution that came into my mind is
tr -d '\n' < file | grep -e "CTACCCCAGACAAACTGGTCAGATACCAACCATCAGCGAAACTAACCAAACAAA"
but I know there should be more efficient ways to do that.
pattern="GCTGTAAATA"$'\n'"GCTAGATTA" # $'\n' is Bash's way of mentioning special chars
grep -e "$pattern" file
OR
pattern="GCTGTAAATA
GCTAGATTA" # with an actual newline at the end of the first line
grep -e "$pattern" file

Print new line with sed using variable [duplicate]

This question already has an answer here:
SED command not being run from bash script
(1 answer)
Closed 8 years ago.
I'm trying to print a new line after 'string' using the variable THIS into file.
sed -i '' 'string/a\
${THIS}
' "${f}"
It prints "${THIS}" into file, literally. I've tried using double quotes for sed but that leads to error message:
"sed: 1: "...": command a expects \ followed by text"
I've also tried to Google this and have been browsing this excellent forum but couldn't find anything.
Any idea, please? Thank you!
It should look like this:
THIS="foo"
sed 's/string/string\n'"${THIS}"'/g' file.txt
Btw, if you are unsure I encourage you to be careful using the -i option. I would play with the sed command until I'm sure and only then use -i (which will overwrite the original file)
If you are replacing a literal string (no regex), the replace command might be better than sed here:
replace string "string"$'\n'"${THIS}" file.txt

bash shell to add a new line in a file after a pattern match found [duplicate]

This question already has answers here:
Insert line after match using sed
(8 answers)
Closed 8 years ago.
I have a file ".gitignore" contains various source file name as
src/abc
src/line
src/another
I like to add another line "src/line.cpp" after a match found "src/line"
result would look like as
src/abc
src/line
src/line.cpp
src/another
I am using sed as
set -- "$File" // $File contains src/line
IFS="/"; declare -a Array=($*)
echo "${Array[0]}" // This prints src
echo "${Array[1]}" // This prints line
sed -i '/$Array[0]\/$Array[1]/a $Array[0]\/$Array[1].cpp' $File
The sed command is not working.
I have a feeling that slashes are not properly handled. If I hard code as
sed -i '/src\/line/a src\/line.cpp' $File
then it works.
Any solutions? Thanks in advance!
You properly use double-quotes in echo "${Array[1]}", and the braces {} needed for the array index. But you neglect to do so in your sed line. So try:
sed -i "/${Array[0]}\/${Array[1]} *$/a ${Array[0]}\/${Array[1]}.cpp" .gitignore
I've added an extra $ here for the end of the line, so:
Repeating the command leaves the file unchanged
Reduces risk of inadvertent matches
The space-star-dollar *$ handles the case where a line has blank spaces at the end. You may also want to add a ^ to match the start of line.
Also, your sed command operates on $File; I think you want .gitignore.
But rather than fiddle around with IFS and arrays, it might be cleaner to use bash's parameter substitution. Replace ${Array[0]} and ${Array[1]} with:
${File%/*}
${File#*/}
Finally, you don't even need to do that, if you replace the sed slash / with for example # (but underscore _ would be bad, as it is commonly used in filenames).
So the penultimate command line is:
sed -i "\#$File#a $File.cpp" .gitignore
or, to handle blanks at the end of a line and to avoid spurious matches:
sed -i "\#$File *\$#a $File.cpp" .gitignore
Note only the first # is escaped.
With GNU sed, you can do it like:
sed -i.BAK 's_src/line_\0\n\0.txt_'
As it allows to use other separators than slashes.
You can use it this way:
s='src/line'; r='src/line.cpp'; sed "s~$s~&\n$r~" file
src/abc
src/line
src/line.cpp
src/another

Resources