Insert text in specific lines of a file
awk 'NR==1{print "Exp1"}NR==5{print "Exp2"}1' file
1 at the end means {print}
.
sed '1i\
Exp1
5i\
Exp2
' file
If you want to extend it to more numbers, awk
makes that easy:
awk 'NR%4==1{print "Exp"++i}1' file
With different numbers, we'll just say sed isn't the right tool for the job. It's possible, but not pretty.
As an academic curiosity, here it is in sed:
sed '1{
h
s/^.*$/Exp0/
x
}
x
s/^4//
s/^3/4/
s/^2/3/
s/^1/2/
/^E/ {
s/$/|/
:x
s/0|/1/
s/1|/2/
s/2|/3/
s/3|/4/
s/4|/5/
s/5|/6/
s/6|/7/
s/7|/8/
s/8|/9/
s/9|/|0/
tx
s/^Exp|/Exp1/
p
s/^/1/
}
x' file
If the number of data points (I'm assuming) in each of your experiments (again, I'm assuming) is always 4, you can use this Perl one-liner:
perl -ple '$. % 4 == 1 and print "Exp", ++$i' your_file
How it works
- The
-p
switch tells Perl to loop over the given file(s) line by line (by default) and print each line after executing whatever code you supply. - The
-l
switch tells Perl to automatically append a newline (by default) to eachprint
statement. - The
-e
switch informs Perl that whatever comes after it is code to execute (the code that will be executed before each line of the file is printed). - The special variable
$.
holds the line number currently being processed. If that line number is congruent to 1 modulo 4 ($. % 4 = 1
) it means that we need to insertExp #
before it. - So we test
$. % 4 == 1
and if it's true, we printExp ++$i\n
(where\n
was added by the-l
switch). This works because an undefined variable is given a value of zero by Perl when it's first used as an integer.
To make it work with multiple files
The
$.
variable will not reset its value if you're processing multiple files at once. Obviously, this is not what you want. You can work around this by explicitly writing out the implicit loop created by-p
in the above one-liner so you can manipulate thecontinue
block.perl -le ' while(<>){ $. % 4 == 1 and print "Exp ",++$i } continue { print; # Print the current line if(eof){ # If the next line is the end-of-file close ARGV ; # Close the current filehandle to reset $. $i = 0 ; # Reset the experiment counter if you need } } ' list_of_your_files
Notes
Both of the above solutions will print the modified file(s) to standard output. To emulate an edit in place (i.e. edit the files themselves), add a
-i
switch:perl -pi -le '$. % 4 == 1 and print "Exp", ++$i' your_file
- Proceed similarly for the other solution.
Make sure you don't put another switch directly after
-i
as it interprets anything after it as the extension to use in order to create a backup file.I recommend you test without
-i
first and then add it if the results are satisfactory.
You don't need external languages, a few standard commands can do the trick. For example, to insert something at line 5 of origin.txt you could do:
tmpfile=`mktemp`
head -n4 origin.txt > $tmpfile
echo "I'm line 5 now" >> $tmpfile
tail -n +5 origin.txt >> $tmpfile
mv $tmpfile origin.txt