Add multiple lines at the beginning of the file
I have many files in the same subdirectory that looks like this:
10 A
11 T
12 A
13 C
15 A
i.e. two columns, where the first row always starts with 10.
I would just like to add lines 1-9 to the beginning of each ie file
1
2
3
4
5
6
7
8
9
10 A
11 T
12 A
13 C
15 A
I don't need to add a second column.
I know what I could do
sed -i '1i1' FILE
to add the first line, but do I need to enter this command for every additional line I want to add?
Try
seq 1 9 | cat - file.in > file.out
Where file.in
is the input file you specified and file.out
is the name of the desired output file.
Or, even shorter (thanks @ william-threll):
{ seq 1 9; cat file.in; } > file.out
If you have gnu awk, you can use inplace
awk editing and avoid the final hardcoding number by reading the existing value from the first entry:
awk -i inplace 'FNR==1{for (i=1; i<$1; i++) print i} 1' *.txt
Change *.txt
to a different globe that matches your files.
This is probably the shortest slot you can use.
sed -i -e1i{1..9} *.txt
This is equivalent to
sed -i -e1i1 -e1i2 -e1i3 -e1i4 -e1i5 -e1i6 -e1i7 -e1i8 -e1i9 *.txt
It uses the extension bash
.
You can use Unix / POSIX / Linux utility cat
to concatenate and print files.
You can use it <(seq 5)
as a replacement file to create an initial sequence. So you can do:
$ cat <(seq 5) file
1
2
3
4
5
10 A
11 T
12 A
13 C
15 A
Then, if you want the edit effect to be set, you can do:
$ cat <(seq 5) file > tmp && mv tmp file
Then:
$ cat file
1
2
3
4
5
10 A
11 T
12 A
13 C
15 A
If you haven't seq
, you can do:
$ cat <(echo {1..5} | tr ' ' '\n') file
instead of this. (Using 5 lines versus 9 in your example. Obviously how to change that ...)
If you have many files or want to create a second column, you can create a header row:
$ header=$(for ((x=1; x<=5; x++)); do printf "%s #\n" $x; done)
$ echo "$header"
1 #
2 #
3 #
4 #
5 #
Then you can use this line instead of running seq
or something:
$ cat <(echo "$header") file
1 #
2 #
3 #
4 #
5 #
10 A
11 T
12 A
13 C
15 A
sed -i -e '1!b;'"$(printf 'i%d\n' {1..9})"
This is equivalent to running
sed -i -e '1!b;i1
i2
i3
i4
i5
i6
i7
i8
i9
'
but easier to write. 1!b
skips the rest of the commands on lines other than the first, but you can also use the address 1
.
sed -i -e "$(printf '1i%d\n' {1..9})"
Alternatively, you might want a pure bash:
$ cat file4
10 A
11 T
12 A
13 C
15 A
$ printf '%s\n%s\n' {1..9} "$(<file4)"
1
2
3
4
5
6
7
8
9
10 A
11 T
12 A
13 C
15 A
To replace the original content of a file, you can do it like this:
printf '%s\n%s\n' {1..9} "$(<file4)" >file44 && mv -f file44 file4
Also sed -i
this is what it does in the background (check sed manpages)
For multiple files, you can use a loop:
for f in *;do printf '%s\n%s\n' {1..9} $(<"$f") >tmp"$f" && mv tmp"$f" "$f";done
You can insert multiple lines with by sed
placing a backslash after the command i
.
sed -i '1i\
1\
2\
3\
4\
5\
6\
7\
8\
9\
' file
This might work for you (GNU sed):
sed -i '1e seq 9' file1 file2 file3 ...
The first line of each file evaluates the command seq 9
.