How to replace all occurrences in 1 file with sed? - linux

I need to replace all occurrences and write back to the same file
I tried:
sed 's/one/two/g' file.txt
this print out but does not write to file
I also tried
sed 's/one/two/g' file.txt>file.txt
This results in empty file
sed -i 's/one/two/g' file.txt
gives error: sed: 1: "file.txt": invalid command code f
Any idea?

For Mac: Use -i.bak to add a backup file
sed -i.bak 's/one/two/g' file.txt
Or
sed -i '' 's/one/two/g' file.txt
For Linux:
Use sed -i on to do infile substitution
sed -i 's/one/two/g' file.txt
You can also do something like below using a tmp file:
sed 's/one/two/g' file.txt > tmp.txt && mv tmp.txt file.txt

Related

How to remove the multiple lines in the file using sed

The test.txt file contains 3 lines:
STREET=main
PHONE=123
EMAIL=abc#xyz.com
To remove two lines with the STREET and EMAIL I run the sed twice in a row:
sed -i -- 's/STREET=.*//' test.txt
sed -i -- 's/EMAIL=.*//' test.txt
Instead of using the sed command twice I would rather remove both lines with a single sed command. How to do it?
To delete (d) lines which contain STREET= or EMAIL=.
sed -i -- '/STREET=/d; /EMAIL=/d' file
sed -i -- 's/STREET=.*//;s/EMAIL=.*//' test.txt
The following sed one-liners show how to remove/empty the target lines:
Empty the target lines:
kent$ sed 's/^\(EMAIL\|STREET\)=.*//' file
PHONE=123
Remove the target lines:
kent$ sed '/^\(EMAIL\|STREET\)=/d' file
PHONE=123
Using pattern ^\(EMAIL\|STREET\)= will avoid to touch lines like USER_EMAIL=... or SOME_STREET=

UNIX sed command not removing spaces in cat output

I have a file as below.
Hi this is first line
this is second line
this is third line
Expected is:
Hi this is first line
this is second line
this is third line
What i used is
cat file.txt | sed 's/ //g'
returns,
Hi this is first line
this is second line
this is third line
For a portable sed command use this:
sed 's/^[[:blank:]]*//' file
[[:blank:]] matches space or tab.
EDIT: To remove all spaces using awk:
awk '{$1=$1}1' OFS= file
OR sed:
sed 's/[[:blank:]]*//g' file
sed in your example will replace all the spaces
sed 's/^[ \t]*//' file.txt
cat file.txt | sed -e 's/^[ \t]*//'
OR
sed 's/^[ \t]*//' file.txt
OR if you want to modify file.txt and remove the white spaces in the beginning of the line :
sed -i 's/^[ \t]*//' file.txt
try this line
sed -r 's/^\s*//' file
to remove all spaces(tabs): sed -r 's/\s//g' file
kent$ echo "Hi this is first line
this is second line
this is third line"|sed -r 's/\s//g'
Hithisisfirstline
thisissecondline
thisisthirdline
The most efficient way to remove all blanks from your input is probably not using sed at all, but
tr -d '[:blank:]' < file.txt
That's different from what you have originally asked for, though (removing initial whitespace only).

How can I combine sed commands to a shell script [duplicate]

This question already has answers here:
Combining two sed commands
(2 answers)
Closed 7 years ago.
I Have to Operate the following sed commands over a file to remove some lines in that file. How can I make this a shell scipt with the file name as a variable. Or is there any simple way to do this as a shell script
sed -i '/^Total/d' delhi222517.txt
sed -i '/^CBSE/d' delhi222517.txt
sed -i '/^Keyword wise/d' delhi222517.txt
sed -i '/^wise/d' delhi222517.txt
sed -i '/^Select A/d' delhi222517.txt
sed -i '/^Enter A/d' delhi222517.txt
sed -i '/^(Keyword/d' delhi222517.txt
sed -i '/^State Name/d' delhi222517.txt
sed -i '/^SNo/d' delhi222517.txt
sed -i '/^Disclaimer/d' delhi222517.txt
sed -i '/^provided/d' delhi222517.txt
sed -i '/^at$/d' delhi222517.txt
sed -i '/^Designed/d' delhi222517.txt
sed -i '/^National/d' delhi222517.txt
sed -i '/^$/d' delhi222517.txt
sed -i '/^\t$/d' delhi222517.txt
sed -i '/^\s$/d' delhi222517.txt
sed -i '/^ /d' delhi222517.txt
sed -i '/^ /d' delhi222517.txt
sed -i 's/^\([0-9]\)/--\1/g' delhi222517.txt
The variable thing is easy:
F=delhi222517.txt
sed -i '/^Total/d' "$F"
...
Or if you want to pass the name of the file as argument to your script:
F="$1"
sed -i '/^Total/d' "$F"
...
But it is better to use the sed options to call it only once. You can use:
sed -i \
-e '/^Total/d' \
-e '/^CBSE/d' \
-e '/^Keyword wise/d' \
... \
delhi222517.txt
Or you can write a file with the full script:
sed -i -f script.sed delhi222517.txt
Or if you feel geek enough, you can use the standard input:
sed -i -f - delhi222517.txt << EOF
/^Total/d
/^CBSE/d
/^Keyword wise/d
...
EOF
On the Command Line
On the command line, you can separate sed commands with semi-colons or with multiple expression arguments. As generic examples:
# Using Semi-Colons
sed -i 's/foo/bar/; s/baz/quux/' infile
# Using Multiple Expressions
sed -i -e 's/foo/bar/' -e 's/baz/quux/' infile
Write a Full-Fledged Sed Script
In general, though, if your commands are numerous, stop using one-liners and build a full-fledged sed script. For example, you could create a file named /tmp/foo.sed containing the following commands from your question:
/^Total/d
/^CBSE/d
/^Keyword wise/d
/^wise/d
/^Select A/d
/^Enter A/d
/^(Keyword/d
/^State Name/d
/^SNo/d
/^Disclaimer/d
/^provided/d
/^at$/d
/^Designed/d
/^National/d
/^$/d
/^\t$/d
/^\s$/d
/^ /d
/^ /d
s/^\([0-9]\)/--\1/g
Then invoke your commands all at once. For example, using GNU sed:
infile='delhi222517.txt'
script='/tmp/foo.sed'
sed --in-place --file="$script" "$infile"
Well you can put them in a a shell script like this:
#!/bin/bash
# some sanity checks
file="$1"
sed -i '/^Total/d' "$file"
sed -i '/^CBSE/d' "$file"
sed -i '/^Keyword wise/d' "$file"
sed -i '/^wise/d' "$file"
#.. more sed commands
btw your various sed commands can be combined into 1 or fewer sed command using reges like:
sed -r -i '/^(Total|CBSE)/d' "$file"
If your script is not going to run any program other than sed your file, then this may be the cleanest way to set it up:
#!/bin/sed -f # <- run the file passed to the program from the command-line
/^Total/Id # /I is the case-insensitive flag, replacing sed -i
/^CBSE/Id
/^Keyword wise/Id
/^wise/Id
/^Select A/Id
/^Enter A/Id
...
Make the above script executable, and then just pass it the filename that you wish to convert:
./mysedscript delhi222517.txt
Using awk you can do all in go:
file=delhi222517.txt
awk '!/^(Total|CBSE|Keyword wise|wise)/' "$file"

Redirecting and writing in the same file

Hi i have a script which replaces the certain occurrences in the .sql files and after that writes it in the some new file.So,i m here unnecessarily creating extra files.Is there anyway by which i can write in the same file.
Below is the part of the script:
sed "s/v1/$value1/g" Save.sql >> CreateViewFinal1.sql
sed "s/v2/$value2/g" CreateViewFinal1.sql >> CreateViewFinal2.sql
sed "s/v3/$value3/g" CreateViewFinal2.sql >> CreateViewFinal3.sql
sed "s/v4/$value4/g" CreateViewFinal3.sql >> CreateViewFinal4.sql
sed "s/v5/$value5/g" CreateViewFinal4.sql >> CreateViewFinal5.sql
sed "s/v6/$value6/g" CreateViewFinal5.sql >> CreateViewFinal6.sql
sed "s/v7/$value7/g" CreateViewFinal6.sql >> CreateViewFinal7.sql
sed "s/v8/$value8/g" CreateViewFinal7.sql >> CreateViewFinal8.sql
sed "s/v9/$value9/g" CreateViewFinal8.sql >> CreateViewFinal9.sql
sed "s/a1/$value10/g" CreateViewFinal9.sql >> CreateViewFinal10.sql
sed "s/b1/$value11/g" CreateViewFinal10.sql >> CreateViewFinal11.sql
sed "s/c1/$value12/g" CreateViewFinal11.sql >> CreateViewFinal12.sql
sqlplus -S -L cimkroger/cimkroger#orcl #CreateViewFinal12.sql
Thanks in advance.
You can sed's inline editing and can avoid multiple sed commands with -e switch like this:
sed -i.bak -e "s/v1/$value1/g" -e "s/v2/$value2/g" -e "s/v3/$value3/g" Save.sql
Yes.
You can change a file directly with the -i option of sed.
Hence, sed -i .... file will replace something in the same file.
Moreover, instead of so many sed different lines, you can do multiple sed actions with the -e option. So instead of:
sed "s/v1/$value1/g" Save.sql >> CreateViewFinal1.sql
sed "s/v2/$value2/g" CreateViewFinal1.sql >> CreateViewFinal2.sql
sed "s/v3/$value3/g" CreateViewFinal2.sql >> CreateViewFinal3.sql
You can do
sed -i -e "s/v1/$value1/g" -e "s/v2/$value2/g" -e "s/v3/$value3/g" Save.sql
and so on.
Example
$ cat file
hello you
$ sed -i -e 's/hello/bye/g' -e 's/you/me/g' file
$ cat file
bye me

Find a string and add multiple lined string saved in variable before

I have been trying quite a few ways with no luck. I have a file named test.txt that has some lorem ipsum and the text [staging: production] I simply want to add a few lines that I have saved in a variable in before it.
If you could explain where I have gone wrong with any of the below it would be much appreciated!
#!/bin/bash
test="lala\
kjdsh"
sed '/^#$/{N; /[staging: production]/ i \
<Location /cgis> \
</Location>\
}' ./test.txt
sed -i -e 's/\[staging\: production\]/\$test/g' ./test.txt
#sed -i 's/Lorem/beautiful/g' test.txt
#awk -v data=$test '{A[NR]=$0}/\[staging\: production\]/{ print data }' test.txt > testfile.txt
#read -a text <<<$(cat test.txt)
#echo ${#text[#]}
#for i in ${text[#]};
#do
# echo -n $i;
# sleep .2;
#done
#ed -s test.txt <<< $'/\[staging\: production\]/s/lalalala/g\nw'
#awk -v data=$test '/\(/\[staging\: production\]\)/ { print data }' test.txt > testfile.txt
# && mv testfile.txt test.txt
#sed -i -e '/\(\[staging\: production\]\)/r/$test\1/g' test.txt
#sed "/\(\[staging\: production\]\)/s//$test\1/g" test.txt
sed -i -e 's/\[staging\: production\]/\$test/g' ./test.txt
won't work because inside singe quotes BASH will not expand \$test.
Therefore you don't need to escape the $.
If you want to substitute with the contents of the variable $test do:
sed -i -e 's/\[staging: production\]/'$test'/g' ./test.txt
You also do not need to escape :
To insert before your pattern works for me this way:
sed -i -e '/\[staging: production\]/ i '$test'' ./test.txt
However to preserve the linebreak inside the variable I needed to define:
test="lala\nkjdsh"
Please note the \n to encode the linebreak.
Try it in perl, it seems to work fine:
perl -pe '{$rep="what\nnow"; s/(\[foo foo2\])/$rep$1/}' file
This might work for you (GNU sed):
test="lala\\
kjdsh"
sed '/\[staging: production\]/i\'"$test" test.txt
N.B. \\ in the variable and the variable is surrouded by "'s in the sed command.

Resources