7

I do not want:

$ cat file > dummy; $ cat header dummy > file

I want similar to the command below but to the beginning, not to the end:

$ cat header >> file
Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
hhh
  • 50,788
  • 62
  • 179
  • 282

8 Answers8

9

You can't append to the beginning of a file without rewriting the file. The first way you gave is the correct way to do this.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
3

This is easy to do in sed if you can embed the header string directly in the command:

$ sed -i "1iheader1,header2,header3"

Or if you really want to read it from a file, you can do so with bash's help:

$ sed -i "1i$(<header)" file

BEWARE that "-i" overwrites the input file with the results. If you want sed to make a backup, change it to "-i.bak" or similar, and of course always test first with sample data in a temp directory to be sure you understand what's going to happen before you apply to your real data.

daveadams
  • 131
  • 3
2

The whole dummy file thing is pretty annoying. Here's a 1-liner solution that I just tried out which seems to work.

    echo "`cat header file`" > file

The ticks make the part inside quotes execute first so that it doesn't complain about the output file being an input file. It seems related to hhh's solution but a bit shorter. I suppose if the files are really large this might cause problems though because it seems like I've seen the shell complain about the ticks making commands too long before. Somewhere the part that is executed first must be stored in a buffer so that the original can be overwritten, but I'm not enough of an expert to know what/where that buffer would be or how large it could be.

Rob
  • 21
  • 2
  • UPDATE: This approach seems to have trashed some source files I was trying to prepend a copyright notice onto. It seems to have quit when it encoutered single quotes in the source files and converted escape sequences into the characters. I guess it's not so useful. – Rob Jul 09 '13 at 17:33
  • UPDATE 2: The command seems to work okay from the command line, but was interpreting the escape sequences from a script I was using to prepend many files at a time. I thought at first it was not using the default 'echo -E' but that still didn't fix it. Apparently the problem had to do with using '#\bin\sh' in the beginning of the script. From an 'sh' instead of a 'bash' command line, the escape sequences get interpreted all the time. I modfied my script so that the first line was '#\bin\bash' instead and things appear to work correctly. Moral: problematic with sh... not sure why? – Rob Jul 16 '13 at 18:00
1

One possibility is to use a here-document:

cat > "prependedfile" << ENDENDEND
prepended line(s)
`cat "file"`
ENDENDEND

There may be a memory limitation to this trick.

Urhixidur
  • 2,270
  • 2
  • 19
  • 24
1

You can't prepend to a file without reading all the contents of the file and writing a new file with your prepended text + contents of the file. Think of a file in Unix as a stream of bytes - it's easy to append to an end of a stream, but there is no easy operation to "rewind" the stream and write to it. Even a seek operation to the beginning of the file will overwrite the beginning of with any data you write.

rlotun
  • 7,897
  • 4
  • 28
  • 23
0

Thanks to right searchterm!

echo "include .headers.java\n$(cat fileObject.java )" > fileObject.java

Then with a file:

echo "$(cat .headers.java)\n\n$(cat fileObject.java )" > fileObject.java
hhh
  • 50,788
  • 62
  • 179
  • 282
  • 2
    That contains a race condition; sometimes (if not always), the shell will set up your stdout redirection, which will zero out the file, before the second "cat" command is complete. – pra Mar 24 '10 at 04:07
  • @pra: fixed? $ echo "$( read -t 1; cat one) \n\n $(cat two)" > one? – hhh May 12 '12 at 14:21
0

if you want to pre-pend "header" to "file" why not append "file" to "Header"

cat file >> header
Jack
  • 10,943
  • 13
  • 50
  • 65
larry
  • 1
0

Below is a simple c-shell attempt to solve this problem. This "prepend.sh" script takes two parameters:

  • $1 - The file containing the pre-appending wording.
  • $2 - The original/target file to be modified.
#!/bin/csh
if (if ./tmp.txt) then
  rm ./tmp.txt
endif

cat $1 > ./tmp.txt
cat $2 >> ./tmp.txt

mv $2 $2.bak
mv ./tmp.txt $2
TobiMcNamobi
  • 4,687
  • 3
  • 33
  • 52