unix sed and redirection [duplicate] - unix

This question already has answers here:
Find and replace in file and overwrite file doesn't work, it empties the file
(12 answers)
Closed 6 years ago.
I am trying to modify a file using sed in a linux server (Ubuntu 16.04).
Here is an example of the code I am running:
sed 's/lineToChange/newString/' example.txt > example.txt
I feel like I should see newString in example.txt after executing this command since the result of the sed command (which prints newString when executed by itself without the redirect) is redirected to overwrite the example.txt content.
Unfortunately the file ends up empty when I do this...
My common sense is telling me that this should be right but clearly there is something I just don't understand here.

If you want to edit a file inline, you should use the -i option:
sed -i 's/lineToChange/newString/' example.txt
This runs sed into a new file and moves that file to example.txt. Whenever you do ">", you essentially empty out example.txt which makes it empty for sed to work on.

Related

sed to substitute words in a file [duplicate]

This question already has answers here:
In-place edits with sed on OS X
(8 answers)
Closed 6 years ago.
I try to learn Unix and how to use the terminal. I am in a Mac
I open the terminal, I go to a folder. Inside there is the file fruit.txt. In that file there are only the words pear, apple
I want to substitute the word pear and put mango in the file fruit.txt
sed 's/pear/mango/' fruit.txt
the terminal gives me:
mango, apple
But I open the file and nothing changed. What am I missing?
sed is a stream editor. This means that it reads data, changes it,
and sends the result to output. It doesn’t automatically replace the
contents of a file.
sed -i or sed --in-place will replace the file as you want.
Alternatively, you can do something like this:
sed fruit.txt > newfruit.txt
and the output will go to a new file. This is safer; if you make a
mistake, you still have your original file.

sed usage not able to understand

I have come across unix sed command usage and not able to understand what it does. Could you please help me to understand the usage ? If possible please share some reference to understand such usages of sed command.
sed -i '/^export JAVA_HOME/ s:.*:export JAVA_HOME=/usr/java/default\nexport HADOOP_PREFIX=/usr/local/hadoop\nexport HADOOP_HOME=/usr/local/hadoop\n:' $HADOOP_PREFIX/etc/hadoop/hadoop-env.sh
The command is simple, though it assumes GNU sed because of the way it uses the -i option; for macOS Sierra and related systems, you'd need to use -i '' in place of just -i.
Overall, it corresponds to:
sed -i '/Pattern/ s:.*:Replacement:' file
where:
-i means overwrite each input file with its edited output without creating a backup copy.
/Pattern/ is ^export JAVA_HOME; a line starting with the word export and then JAVA_HOME separated by a single space.
s:.*:Replacement: is a substitute command, using : instead of the more conventional / (often s/.*/Replacement/) as the pattern delimiter. This is done because the replacement text contains slashes. The .* matches the whole line. The rest of the material is written in place of the original export JAVA_HOME line. The \n sequence expands to a newline, so it actually produces a number of lines in the output.
file is $HADOOP_PREFIX/etc/hadoop/hadoop-env.sh
As others have pointed out, this is a sed command invocation. The command is short for "Stream EDitor" and is quite useful for modifying files programaticallly. Your best bet is to read the man pages (man sed, but I've broken down your particular command here for instructive purposes:
sed # The command
-i # Edit file in place (no backup)
'/^export JAVA_HOME/ # For every line that begins with 'export JAVA_HOME'...
s: # substitue...
.*: # the entire line with...
export JAVA_HOME=/usr/java/default
export HADOOP_PREFIX=/usr/local/hadoop
export HADOOP_HOME=/usr/local/hadoop
:' # End of command
$HADOOP_PREFIX/etc/hadoop/hadoop-env.sh # Run on the following file
Points of interest:
Commands can be limited to a particular address range or scope. Here, the scope was a search.
The substitue command can be delimited by almost any character (usually it is /, but in this case, : was chosen to prevent escaping of the / in the filepaths
The sed expression was enclosed in ' to prevent shell expansion of variables. Although no expansions would have taken place in this scenario, it is fairly common to see the expression wrapped in ' to eliminate the possibility.

Inserting a string using Sed that will not evaluate as a command

I'm trying to insert into a text file the string cd $var at the second line using sed, but it doesn't seem to work. I'm using the syntax for inserting a line at a specific line in a file,
sed -i '2icd $var' FILE
The format of which was found as the response to this question:
Insert a line at specific line number with sed or awk
My best guess is that sed is interpreting the command literally and evaluating it instead of copying it in. However, all of my attempts at forcing it to be evaluated simply as a string have failed. My attempts so far:
sed -i '2i\cd $var' FILE
sed -i '2i\cd \$var' FILE
sed -i "2i'cd $var'" FILE
and
Line='cd $var'
sed -i "2i$Line" FILE
I was fairly sure this last attempt would succeed, due to the hard quotes, but it still failed.
In fact, this also failed,
sed -i '2icd' FILE
Yet this succeeded (Just to confirm the general format):
sed -i '2ic' FILE
Just to be clear, all 5 of the failed attempts yielded the same error: A blank line was inserted at the desired location.
sed -i "2 i\\
$var" file
need a escape NewLine normaly after the i and depending the OS/sed a space before and/or after the i also. Finaly, with double quote, escape the \

Delete all contents of the file using sed

I want to empty a file using sed command. I searched lot of forums and tutorial. There is no available to delete all contents of the file. How to delete all contents of the file using sed command.
It looks like a strange request. Anyway, this is a way:
sed -i '/^/d' file
sed -i does an in-place replacement.
/^/ matches lines, in this case all of them because ^ means "beginning of line".
/d deletes them.
Or shorter (thanks glenn jackman as always):
sed -i d file
You don't need sed for this. To empty a file:
> filename
with no command, that redirection will truncate the file.
Try this sed. It will remove all.
sed -ni '' file
n do not print if not told to do so.
i in place.
Since no code is given, file will be replaced by nothing.

sed -i option is not working on solaris

I am using sed to replace a line with NULL in a file. The command i used is
sed -i "s/.*shayam.*//g" FILE
This is working fine in linux. shayam is replaced with blank in the FILE. But when i used this in solaris it is showing some error.
sed: illegal option -- i
How to use -i functionality of sed in solaris. Kindly help.
The -i option is GNU-specific. The Solaris version does not support the option.
You will need to install the GNU version, or rename the new file over the old one:
sed 's/.shayam.//g' FILE > FILE.new && mv FILE.new FILE
I just answered a similar question sed -i + what the same option in SOLARIS, but for those who find this thread instead (I saw it in the related thread section):
The main problem I see with most answers given is that it doesn't work if you want to modify multiple files. The answer I gave in the other thread:
It isn't exactly the same as sed -i, but i had a similar issue. You
can do this using perl:
perl -pi -e 's/find/replace/g' file
doing the copy/move only works for single files. if you want to
replace some text across every file in a directory and
sub-directories, you need something which does it in place. you can do
this with perl and find:
find . -exec perl -pi -e 's/find/replace/g' '{}' \;
sed doesn't haven an -i option.
You are probably using some vendor-specific variant of sed. If you want to use the vendor-specific non-standardized extensions of your vendor-specific non-standardized variant of sed, you need to make sure that you install said vendor-specific non-standardized variant and need to make sure that you call it and don't call the standards-compliant version of sed that is part of your operating environment.
Note that as always when using non-standardized vendor-specific extensions, there is absolutely no guarantee that your code will be portable, which is exactly the problem you are seeing.
In this particular case, however, there is a much better solution: use the right tool for the job. sed is a stream editor (that's why it is called "sed"), i.e. it is for editing streams, not files. If you want to edit files, use a file editor, such as ed:
ed FILE <<-HERE
,s/.shayam.//g
w
q
HERE
See also:
Unable to use SED to edit files fast
How can I replace a specific line by line number in a text file?
Either cat the file or try <?
Then pipe (|) the result to a temp file and if all goes well (&&) mv the tempfile to the original file.
Example:
cat my_file | sed '!A!B!' > my_temp_file && mv my_temp_file my_file

Resources