How to substitute without creating intermediate file in sed? - linux

I was doing some hands-on with the Unix sed command. I was trying out the substitution and append command, in a file. But the difficulty is, I have to create an intermediate file, and then do mv to rename it to the original file.
Is there any way to do it at one shot in the same file?
[root#dhcppc0 practice]# sed '1i\
> Today is Sunday
> ' file1 > file1
[root#dhcppc0 practice]# cat file1
[root#dhcppc0 practice]#
The file is deleted!
[root#dhcppc0 practice]# sed 's/director/painter/' file1 > file1
[root#dhcppc0 practice]# cat file1
The file is deleted!

Try this -
sed -i '' 's/originaltext/replacementtext/g' filename | cat filename
-i '' is meant for providing a backup file. If you are confident your replacement won't cause an issue you can put '' to pass no backup file
/g is for replacing globally. If you have more than one originaltext in one line then with /g option will replace all else it will only replace the first.

GNU sed knows an option -i which does in-place edit of the given files.
When doing an operation file1 > file1 what actually happens is, that the file is opened and truncated by the shell before the program (which gets it's name as argument) comes around reading anything from it.
Update:
sed's man page states the following on the -i option (thanks Delan for mentioning it):
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)

sed -i.bak 's/director/painter/' file1
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)

Related

How to replace a entire line from a file which has a content /u02/app/oracle-1/product/12.2.0/db_1:N to /u01/app/oracle/product/12.2.0/db_1:Y

Can we do it using sed and if so how?
How to replace a entire line from a file which has a content /u02/app/oracle-1/product/12.2.0/db_1:N to /u01/app/oracle/product/12.2.0/db_1:Y using Sed
It is very easy with sed command. Use below sed command which will do it for you.
sed 's|'/u02/app/oracle-1/product/12.2.0/db_1:N'|'/u01/app/oracle/product/12.2.0/db_1:Y'|g' your_original_file > newfile
mv newfile your_original_file
In above example, first sed command will replace /u02/app/oracle-1/product/12.2.0/db_1:N with /u01/app/oracle/product/12.2.0/db_1:Y and modified text will be redirect to newfile. In the new file you can review the changes whether correct or not.
With mv command you can rename newfile to your_original_file. So above example is safe. But you can do so with a single command like below, but you should be careful here, because if anything wrong you will be in trouble :-)
sed -i.bak 's|'/u02/app/oracle-1/product/12.2.0/db_1:N'|'/u01/app/oracle/product/12.2.0/db_1:Y'|g' yourfile
After lot of trials got it done.
sudo sed -i.bak '/^G:/u01/app/oracle/product/12.2.0/db_1:/ s/N/Y/'

find string and stored the replaced string in other file shell script

I want to find a string say 'foo' in a file sat '1.txt' using shell script and replace 'foo' with 'bar' and store the output into other file say '2.txt' without any modification in 1.txt.
so '1.txt' would contain 'foo' itself but '2.txt' will now have all the contents of '1.txt' with 'foo' replaced by 'bar'
I am using this command in bash
sed -i "s/foo/bar/g" "1.txt" > 2.txt
but its not working.
Remove the -i option as it stands for in-place operation.
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
(sed(1) man page)
Remove the -i switch, or provide a backup extension (-i.bak), so the modified file will be 1.txt and 1.txt.bak the original backup.
You don't need quotes on "1.txt", unless the filename contains spaces.
sed "s/foo/bar/g" 1.txt > 2.txt
or
sed -i.bak "s/foo/bar/g" 1.txt
Take a look at sed manual

One line bash Script to Edit File (not create a new one)

I'm a newbie at bash script and I'm trying to write a bash script to edit a configuration file. i want to remove " foo" from the file.
Using the code
echo
sed -e "s/ foo//" ./test > ./test2
will create a new file with the content i want. But if i try to edit the same file using this
echo
sed -e "s/ foo//" ./test > ./test
the file will just become empty. Is this not the way? how can i simply edit a file? thanks.
This is what the -i switch is for: edit-in-place:
sed -i -e "s/ foo//" ./test
The -i switch is documented in man sed:
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
For GNU sed (linux), no back-up is created when the suffix is omitted. For other versions of sed, it might be mandatory to supply a backup suffix.
Empty file
Shell opens the file test for writing -> clearing all its previous contents.
How to edit same file
Solution 1:- inline change
sed -i.bk "s/ foo//" ./test
Solution 2:- use intermediate file (manual version of previous cmd)
sed -e "s/ foo//" ./test > test.bk && mv test.bk test
Sed is a [s]tream [ed]itor, not a text editor. Using the '-i' parameter is not POSIX, plus it adds the overhead of creating a temporary file before replacing the original file.
If you want to edit your files truly in place, you should use ed/ex instead.
ex -sc '%s/ foo//g|xit' ./test
See the manual pages sed(1p), ed(1p) and ex(1p).

Bash - Search and append strings

If I wanted to search for a line in a file and append a string to the end of that line, how can I go about it? I.E.:
file=?
I want to search for file=? and replace the question mark with a file path. The file path is located in a variable $FILEPATH
file=$FILEPATH
Thanks!
EDIT
sed -i -f "s,file=\?,file=$FILEPATH,g"
The above works well and is what I'm looking for but is there a way to replace the question mark? With the code above if I have the following:
FILEPATH=/file/path
Properties file:
something=?
file=?
The replacement produces:
Properties file:
something=?
file=/file/path?
Is there a way to replace the ? completely?
I'd use sed for that:
sed -i "s/file=?/file=$FILEPATH/g" your_file
If your $FILEPATH has / then use a different sed separator, something like:
sed -i "s,file=?,file=$FILEPATH,g"
Don't escape your question mark
[jaypal:~/Temp] cat temp
file=?
file=?
[jaypal:~/Temp] echo $filepath
/usr/bin
[jaypal:~/Temp] sed -e 's_file=?_file='$filepath'_g' temp
file=/usr/bin
file=/usr/bin
Also to make inline changes I would recommend to use the following -
[jaypal:~/Temp] sed -ibak 's_file=?_file='$filepath'_g' temp
[jaypal:~/Temp] ls temp*
temp tempbak
[jaypal:~/Temp] cat temp
file=/usr/bin
file=/usr/bin
[jaypal:~/Temp] cat tempbak
file=?
file=?
This will make a backup copy of your original file before making any changes. In case if anything goes wrong you will have your original copy protected.
If you are using Bash, you can simply use Bash builtins and substitutions instead of sed:
#!/bin/bash
FILEPATH="/file/path"
while read line; do
echo "${line/file=\?/${line/\?/}$FILEPATH}"
done < yourfile

Appending Text To the Existing First Line with Sed

I have a data that looks like this (FASTA format). Note that
in comes with block of 2 ">" header and the sequence.
>SRR018006
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGN
>SRR018006
ACCCGCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
What I want to do is to append a text (e.g. "foo" in the > header)
yielding:
>SRR018006-foo
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGN
>SRR018006-foo
ACCCGCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
Is there a way to do that using SED? Preferably inline modifying
the original file.
This will do what you're looking for.
sed -ie 's/^\(>.*\)/\1-foo/' file
since judging from your previous post, you are also experienced using awk: here's an awk solution.
# awk '/^>/{print $0"-foo";next}1' file
>SRR018006-foo
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGN
>SRR018006-foo
ACCCGCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
# awk '/^>/{print $0"-foo";next}1' file > temp
# mv temp file
if you insist on sed
# sed -e '/^>/s/$/-foo/' file

Resources