This question already has answers here:
Insert newline (\n) using sed
(4 answers)
Insert contents of a file after specific pattern match
(1 answer)
Closed 1 year ago.
I would like to insert the contents of one text file (with newlines) into another at a predetermined location (after some string):
I tried the following:
the base file:
cat base
ONE
TWO
THREE
the extension:
cat ext
100
200
300
400
500
600
700
800
900
A00
B00
C00
D00
and the script I tried:
#!/bin/bash
ext=$(<ext)
sed -i "s/TWO/TWO\n$ext/" base
which gives me sed: -e expression #1, char 14: unterminated `s' command
If you want to edit a file directly, I always suggest ed instead of the non-standard sed -i (Where different implementions of sed that do support it act differently, a common source of questions here):
printf "%s\n" "/TWO/r ext" w | ed -s base
will insert the contents of file ext after the first line containing TWO in base, and then write the new version of base back to disk.
If you must use sed, the proper invocation will look very similar (No surprise since they're sibling commands):
sed -i '/TWO/r ext' base
(This will insert the ext file after every TWO in base, though, not just the first.)
The key in both is the r command, which reads the contents of the given file and inserts it after a line with the matching address. Works a lot better than trying to read the file contents into a variable and including the text directly in the ed/sed commands.
If you want to insert the contents of a variable after the line, you can use
printf "%s\n" "/TWO/a" "$ext" . w | ed -s base
(As long as the variable doesn't have a line with just a period)
or with GNU sed
sed -i "/TWO/a ${ext//$'\n'/\\\n}" base
to append text after the addressed line.
While the answer given by Shawn shows a possible solution, it does not explain why your attempt did not work.
Note that your variable ext contains line feed characters. Hence, sed sees here a physical line feed. You would get the same error message when typing on the command line (in two lines):
sed -i "s/TWO/TWO\nfoo
/" base
This might work for you (GNU sed):
sed -e '0,/TWO/{/TWO/r extFile' -e '}' baseFile
This will place the file extFile after the first occurrence of the string TWO. The -i option may be used to amend the file in place.
An alternative solution:
sed -e '/TWO/!b;r extFile' -e ':a;n;ba' baseFile
N.B. The use of the -e option to split the commands after the r filename command. The r must be followed by a newline and the -e simulates this on a single line.
If you want to insert the file after each occurrence of the string TWO, then just use (as Shawn has already explained):
sed '/TWO/r extFile' baseFile
I have a configuration file (gpsd.default) containing data with the following format:
# If you must specify a non-NMEA driver, uncomment and modify the next line
GPSD_SOCKET="/var/run/gpsd.sock"
GPSD_OPTIONS=""
GPS_DEVICES=""
I am making a change on the file with sed:
sed -i 's/^GPS_DEVICES="".*/GPS_DEVICES="dev/ttyUSB1"/' /etc/default/gpsd.default
or
sed -i '4s/^.*/GPS_DEVICES="dev/ttyUSB1"/' /etc/default/gpsd.default
The above sed command returns error:
sed: bad option in substitution expression
Because the new line contains "/" in its expression.
How to update my sed command to make it work?
This is because you are using a regex containing /, which is the same character sed uses as delimiter.
Just change the sed delimiter to another one, for example ~:
sed -i 's~^GPS_DEVICES="".*~GPS_DEVICES="dev/ttyUSB1"~' /etc/default/gpsd.default
By the way, since you are changing files in /etc, you may want to use -i.bak, so that the original file gets backed up. It is a good practice to prevent loss of important information.
You should update your sed command to this.
sed -i 's/^GPS_DEVICES=\"\".*/GPS_DEVICES=\"dev\/ttyUSB1\"/' /etc/default/gpsd.default
I'm trying to remove one string in one file by using:
sed -i -e '/example/' test.txt
But I've got the following error:
sed: -e expression #1, char 6: missing command
What is it missing and why?
Thanks!
/example/ is an address which tells sed where to run commands - on a line containing the string example. You didn't specify any commands.
This is a commnand that replaces the string example with an empty string:
's/example//'
try:
sed '/example/d' test.txt
Explanation as suggested by #Nathan Tuggy
sed will search for the given string and will 'D'elete it
user#host:~$ cat test.txt
one
two
three
user#host:~$ sed '/two/d' test.txt
one
three
I have a task, to replace specific pattern in a string.
So far I tried commands like sed -e 's/text_to_find/text_to_replace/g' file
but I don't why it changed all string, not just a part which I wanted to change.
what I want to do is in every string that contains word china to add this Tomas_proxy.lt
To make it very clear, what I am looking for, there is file I am using:
987173,businesswirechina.com
988254,chinacfa.com
988808,1012china.com
989146,chinawise.ru
989561,chinaretailnews.com
989817,mobileinchina.cn
990894,cmt-china.com.cn
990965,chinajoy.net
992753,octaviachina.com
993238,chinadftzalex.com
993447,china-kena.com
And this is I would like to see in a new file
987173,Tomas_proxy.lt/businesswirechina.com
988254,Tomas_proxy.lt/chinacfa.com
988808,Tomas_proxy.lt/1012china.com
989146,Tomas_proxy.lt/chinawise.ru
989561,Tomas_proxy.lt/chinaretailnews.com
989817,Tomas_proxy.lt/mobileinchina.cn
990894,Tomas_proxy.lt/cmt-china.com.cn
990965,Tomas_proxy.lt/chinajoy.net
992753,Tomas_proxy.lt/octaviachina.com
993238,Tomas_proxy.lt/chinadftzalex.com
993447,Tomas_proxy.lt/china-kena.com
P.s. This is just example file, In real file I am using, not every line has word china ,there is 100000 strings and lets say about 500 has china
You can try this sed command
sed 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName
or
sed 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName > NewFile
or
sed -i.bak 's/,\(.*china\)/,Tomas_proxy.lt\/\1/' FileName
sed '/[Cc]hina/s/,/,Tomas_proxy.lt\//' File > New_File
In all the lines matching china / China (change if you don't want case check), replace the first , with ,Tomas_proxy.lt/. Output redirected to New_File.
If you want the changes to be in the same file, use -i (inplace option):
sed -i '/[Cc]hina/s/,/,Tomas_proxy.lt\//' File
Her is an awk version:
awk '/china/ {sub(/,/,"&Tomas_proxy.lt/")} 1' file
987173,Tomas_proxy.lt/businesswirechina.com
988254,Tomas_proxy.lt/chinacfa.com
988808,Tomas_proxy.lt/1012china.com
989146,Tomas_proxy.lt/chinawise.ru
989561,Tomas_proxy.lt/chinaretailnews.com
989817,Tomas_proxy.lt/mobileinchina.cn
990894,Tomas_proxy.lt/cmt-china.com.cn
990965,Tomas_proxy.lt/chinajoy.net
992753,Tomas_proxy.lt/octaviachina.com
993238,Tomas_proxy.lt/chinadftzalex.com
993447,Tomas_proxy.lt/china-kena.com
Search for china, if found, replace , with ,Tomas_proxy.lt/, then print all lines.
sed '/china/ s#,#,Tomas_proxy.lt/#' YourFile
based on your sample and assuming first , is the place to insert your text in the line
In looking for a command to delete a line (or lines) from a text file that contain a certain string.
For example
I have a text file as follows
Sat 21-12-2014,10.21,78%
Sat 21-12-2014,11.21,60%
Sun 22-12-2014,09.09,21%
I want to delete all lines that have "21-12-2014" in them.
I'm not able to find a solution that works.
According to #twalberg there is more three alternate solution for this question, which I'm explaining is as follows for future reader of this question for more versatile solutions:
With grep command
grep -v 21-12-2014 filename.txt
explanations:
-v is used to find non-matching lines
With awk command
awk '! /21-12-2014/' filename.txt
explanations:
! is denoting it will print all other lines that contain match of the string. It is not operator signify ignorance.
With sed command
sed -e '/21-12-2014/d' < filename.txt
explanations:
-e is signify scripted regex to be executed
d is denoting delete any match
< is redirecting the input file content to command
Try doing this :
sed -i.bak '/21-12-2014/d' *
A bit of explanations :
sed : the main command line, put the mouse pointer on sed
-i.bak : replace the file in place and make a backup in a .bak file
// is the regex
d means: delete