How can I add a line to a file in a shell script? - linux

I want to add a row of headers to an existing CSV file, editing in place. How can I do this?
echo 'one, two, three' > testfile.csv
and I want to end up with
column1, column2, column3
one, two, three
Changing the initial CSV output is out of my hands.
Any standard command will do. The important thing is the file is edited in place, and the line is inserted at the beginning of the file.

To answer your original question, here's how you do it with sed:
sed -i '1icolumn1, column2, column3' testfile.csv
The "1i" command tells sed to go to line 1 and insert the text there.
The -i option causes the file to be edited "in place" and can also take an optional argument to create a backup file, for example
sed -i~ '1icolumn1, column2, column3' testfile.csv
would keep the original file in "testfile.csv~".

This adds custom text at the beginning of your file:
echo 'your_custom_escaped_content' > temp_file.csv
cat testfile.csv >> temp_file.csv
mv temp_file.csv testfile.csv

This doesn't use sed, but using >> will append to a file. For example:
echo 'one, two, three' >> testfile.csv
Edit: To prepend to a file, try something like this:
echo "text"|cat - yourfile > /tmp/out && mv /tmp/out yourfile
I found this through a quick Google search.

As far as I understand, you want to prepend column1, column2, column3 to your existing one, two, three.
I would use ed in place of sed, since sed write on the standard output and not in the file.
The command:
printf '0a\ncolumn1, column2, column3\n.\nw\n' | ed testfile.csv
should do the work.
perl -i is worth taking a look as well.

sed is line based, so I'm not sure why you want to do this with sed. The paradigm is more processing one line at a time( you could also programatically find the # of fields in the CSV and generate your header line with awk) Why not just
echo "c1, c2, ... " >> file
cat testfile.csv >> file
?

Use perl -i, with a command that replaces the beginning of line 1 with what you want to insert (the .bk will have the effect that your original file is backed up):
perl -i.bk -pe 's/^/column1, column2, column3\n/ if($.==1)' testfile.csv

Add a given line at the beginning of a file in two commands:
cat <(echo "blablabla") input_file.txt > tmp_file.txt
mv tmp_file.txt input_file.txt

how to add line inside a file
sed -i -e "48r../../../../folder1/lines_to_add.txt" a.txt
a.txt - the file you want to change 48r is line number of a.txt some
lines are inside lines_to_add.txt file
../../../../scripts3_2d/lines_to_add.txt
-i update a.txt, try without -i before run the code, be careful with new lines,
"keep a newline at the end of lines_to_add.txt"

Related

How to use sed to comment and add lines in a config-file

I am looking for a way to achieve the following:
A certain directory contains 4 (config) files:
File1
File2
File3
File4
I want my bash script to read in each of the files, one by one. In each file, look for a certain line starting with "params: ". I want to comment out this line and then in the next line put "params: changed according to my will".
I know there are a lot of handy tools such as sed to aid with these kind of tasks. So I gave it a try:
sed -ri 's/params:/^\\\\*' File1.conf
sed -ri '/params:/params: changed according to my will' File1.conf
Questions: Does the first line really substitute the regex params: with \\ following a copy of the entire line in which params: was found? I am not sure I can use the * here.
Well, and how would I achieve that these commands are executed for all of the 4 files?
So this command will comment every line beggining by params: in you files, and append a text in the next line
sed -E -i 's/^(params:.*)$/\/\/\1\nYOUR NEW LINE HERE/g'
the pattern ^(params:.*)$ will match any whole line beggining by params:, and the parenthesis indicate that this is a capturing group.
Then, it is used in the second part of the sed command via \1, which is the reference of the first capturing group found. So you can see the second part comments the first line, add a line break and finally your text.
You can execute this for all your files simply by going sed -E -i 's/^(params:.*)$/\/\/\1\nYOUR NEW LINE HERE/g' file1 file2 file3 file4
Hope this helps!
You can do this:
for i in **conf
do
cp $i $i.bak
sed -i 's/\(params:\)\(.*\)$/#\1\2\n\1new value/'
done
With: \(params:\)\(.*\)
match params: and store it in `\1
match text following .*\: and store it in \2
Then create two lines:
The initial line commented: #\1\2\n
The new line with your wanted value: \1new value
This might work for you (GNU sed and parallel):
parallel --dry-run -q sed -i 's/^params:/#&/;T;aparams: bla bla' {} ::: file[1-4]
Run this in the desired directory and if the commands are correct remove the --dry-run option and run for real.

Want to append records in two file using shell script

My first input file contains records name abc.txt:
abc#gmail.com
bscd#yahoo.co.in
abcd.21#gmail.com
1234#hotmail.com
My second file contains record name details.txt:
123456^atulsample^1203320
I want my final file having output to be Final.txt:
abc#gmail.com^123456^atulsample^1203320
bscd#yahoo.co.in^123456^atulsample^1203320
abcd.21#gmail.com^123456^atulsample^1203320
I have uses sed command but I am not getting my required output.
Kindly help as I don't have much knowledge in shell scripting.
try something like this;
#!/bin/bash
while read -r line
do
detail="$line"
sed '/^[ \t]*$/d' abc.txt | sed "s/$/^${detail}/" >> Final.txt
done < "details.txt"
this is to delete blank lines;
sed '/^[ \t]*$/d' abc.txt
this is to append from details.txt
sed "s/$/^${detail}/"

Insert line in the middle of file with standard unix tools

I can grap a specific line from a file using sed. Is there an easy way to take this line or paragraph and insert onto a specific line in another file?
sed -n 1,10p >> foo appends the result to foo, which places it at the bottom. Is there a standard unix tool to insert onto a specific line?
Perhaps you are looking for sed's r command?
sed '123r file.txt' main.txt
inserts the contents of file.txt at line 123 of main.txt, printing everything to standard output.
(If your sed has the -i option, you can make it modify main.txt directly; otherwise, it will not modify its input files.)
If you want to replace the nth line in file foo you can do it with
cp foo foo.tmp
head -n $((n-1)) foo.tmp > foo
echo "newline" >> foo
tail -n +$((n+1)) foo.tmp >> foo
So you take the first n-1 lines with head -n NR, append your new line and then append the rest starting from line n+1 with tail -n +NR.
This might work for you (GNU sed):
sed '123s|.*|sed '\''1,10!d'\'' insert.txt|e' main.txt

How can i add StdOut to a top of a file (not the bottom)?

I am using bash with linux to accomplish adding content to the top of a file.
Thus far i know that i am able to get this done by using a temporary file. so
i am doing it this way:
tac lines.bar > lines.foo
echo "a" >> lines.foo
tac lines.foo > lines.bar
But is there a better way of doing this without having to write a second file?
echo a | cat - file1 > file2
same as shellter's
and sed in one line.
sed -i -e '1 i<whatever>' file1
this will insert to file1 inplace.
the sed example i referred to
tac is very 'expensive' solution, especially as you need to use it 2x. While you still need to use a tmp file, this will take less time:
edit per notes from KeithThompson, now using '.$$' filename and condtional /bin/mv.
{
echo "a"
cat file1
} > file1.$$ && /bin/mv file1.$$ file1
I hope this helps
Using a named pipe and in place replacement with sed, you could add the output of a command at the top of a file without explicitly needing a temporary file:
mkfifo output
your_command >> output &
sed -i -e '1x' -e '1routput' -e '1d' -e '2{H;x}' file
rm output
What this does is buffering the output of your_command in a named pipe (fifo), and inserts in place this output using the r command of sed. For that, you need to start your_command in the background to avoid blocking on output in the fifo.
Note that the r command output the file at the end of the cycle, so we need to buffer the 1st line of file in the hold space, outputting it with the 2nd line.
I write without explicitly needing a temporary file as sed might use one for itself.

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