Prepend Line to Beginning of a File

How to insert a text at the beginning of a file?

sed can operate on an address:

$ sed -i '1s/^/<added text> /' file

What is this magical 1s you see on every answer here? Line addressing!.

Want to add <added text> on the first 10 lines?

$ sed -i '1,10s/^/<added text> /' file

Or you can use Command Grouping:

$ { echo -n '<added text> '; cat file; } >file.new
$ mv file{.new,}

How can I prepend a line to the beginning of a file?

You can't do this directly in any programming language. See some other questions on the same topic in C#, Python, NodeJs, PHP, Bash and C.

There are several solutions with different trade-offs:

  1. Copy the entire file into memory, write the data you want, and then write the rest of the file after it. If the file is large, this might be a bad solution because of the amount of memory it will use, but might be suitable for small files, because it is simple to implement.

  2. Use a buffer, the same size as the text you want to prepend. Copy chunks of the file at a time into memory and then overwrite it with the previous chunk. In this way, you can shuffle the contents of the file along, with the new text at the start. This is likely to be slower than the other approaches, but will not require a large memory allocation. It could also be the best choice when the process doesn't have permission to delete the file. But be careful: If the process is interrupted, this approach could leave the file in a corrupted state.

  3. Write the new data to a temporary file and then append the contents of the original. Then delete the original and rename the temporary file. This is a good solution because it delegates the heavy lifting to the operating system, and the original data is backed up so will not be corrupted if the process is interrupted.

From searching on Stack Overflow, the third solution seems to be the most popular answer for other languages, e.g. in Bash. This is likely to be because it is fast, safe and can often be implemented in just a few lines of code.

A quick Rust version looks something like this:

extern crate mktemp;
use mktemp::Temp;
use std::{fs, io, io::Write, fs::File, path::Path};

fn prepend_file<P: AsRef<Path>>(data: &[u8], file_path: &P) -> io::Result<()> {
// Create a temporary file
let mut tmp_path = Temp::new_file()?;
// Stop the temp file being automatically deleted when the variable
// is dropped, by releasing it.
tmp_path.release();
// Open temp file for writing
let mut tmp = File::create(&tmp_path)?;
// Open source file for reading
let mut src = File::open(&file_path)?;
// Write the data to prepend
tmp.write_all(&data)?;
// Copy the rest of the source file
io::copy(&mut src, &mut tmp)?;
fs::remove_file(&file_path)?;
fs::rename(&tmp_path, &file_path)?;
Ok(())
}

Usage:

fn main() -> io::Result<()> {
let file_path = Path::new("file.txt");
let data = "Data to add to the beginning of the file\n";
prepend_file(data.as_bytes(), &file_path)?;
Ok(())
}

Insert a new line at the beginning of a file

Here's a way to add a line to the beginning of a file:

sed -i '1s/^/line_to_be_added\n/' file

Then, you could use the code above with find to achieve your ultimate goal:

find . -type f -name '*.js' -exec sed -i '1s/^/line_to_be_added\n/' {} \;

Note: this answer was tested and works with GNU sed.

Edit: the code above would not work properly on a .js file that is empty, as the sed command above does not work as expected on empty files. A workaround to that would be to test if the file is empty, and if it is, add the desired line via echo, otherwise add the desired line via sed. This all can be done in a (long) one-liner, as follows:

find . -type f -name '*.js' -exec bash -c 'if [ ! -s "{}" ]; then echo "line_to_be_added" >> {}; else sed -i "1s/^/line_to_be_added\n/" {}; fi' \;

Edit 2: As user Sarkis Arutiunian pointed out, we need to add '' before the expression and \'$' before \n to make this work properly in MacOS sed. Here an example

sed -i '' '1s/^/line_to_be_added\'$'\n/' filename.js

Edit 3: This also works, and editors will know how to syntax highlight it:

sed -i '' $'1s/^/line_to_be_added\\\n/' filename.js

How can I prepend a string to the beginning of each line in a file?

a one-line awk command should do the trick also:

awk '{print "prefix" $0}' file

C#: Prepending to beginning of a file

Adding to the beginning of a file (prepending as opposed to appending) is generally not a supported operation. Your #1 options is fine. If you can't write a temp file, you can pull the entire file into memory, preprend your data to the byte array and then overwrite it back out (this is only really feasible if your files are small and you don't have to have a bunch in memory at once because prepending the array is not necessarily easy without a copy either).

Unix command to prepend text to a file

sed -i.old '1s;^;to be prepended;' inFile
  • -i writes the change in place and take a backup if any extension is given. (In this case, .old)
  • 1s;^;to be prepended; substitutes the beginning of the first line by the given replacement string, using ; as a command delimiter.

Prepend line to beginning of a file

In modes 'a' or 'a+', any writing is done at the end of the file, even if at the current moment when the write() function is triggered the file's pointer is not at the end of the file: the pointer is moved to the end of file before any writing. You can do what you want in two manners.

1st way, can be used if there are no issues to load the file into memory:

def line_prepender(filename, line):
with open(filename, 'r+') as f:
content = f.read()
f.seek(0, 0)
f.write(line.rstrip('\r\n') + '\n' + content)

2nd way:

def line_pre_adder(filename, line_to_prepend):
f = fileinput.input(filename, inplace=1)
for xline in f:
if f.isfirstline():
print line_to_prepend.rstrip('\r\n') + '\n' + xline,
else:
print xline,

I don't know how this method works under the hood and if it can be employed on big big file. The argument 1 passed to input is what allows to rewrite a line in place; the following lines must be moved forwards or backwards in order that the inplace operation takes place, but I don't know the mechanism

Prepend ! to the beginning of the first line of a file

You sent an array to Set-Content with $b,$a. Each array item will be given its own line as you have seen. It would displayed the same way on the prompt if executed.

As long as the file is not too big read it in as one string and add the character in.

$path = 'hh_Regulars3.csv'
"!" + (Get-Content $path -Raw) | Set-Content $path

If you only have PowerShell 2.0 then Out-String would work in place of -Raw

"!" + (Get-Content $path | Out-String) | Set-Content $path

The brackets are important to be sure the file is read in before it goes to through the pipeline. It allows us to both read and write on the same pipeline.

If the file is larger look into using StreamReaders and StreamWriters. This would also have to be used if the trailing new line, created by the Add-Content and Set-Content, is not warranted.

Prepend a line to an existing file in Python

Python makes a lot of things easy and contains libraries and wrappers for a lot of common operations, but the goal is not to hide fundamental truths.

The fundamental truth you are encountering here is that you generally can't prepend data to an existing flat structure without rewriting the entire structure. This is true regardless of language.

There are ways to save a filehandle or make your code less readable, many of which are provided in other answers, but none change the fundamental operation: You must read in the existing file, then write out the data you want to prepend, followed by the existing data you read in.

By all means save yourself the filehandle, but don't go looking to pack this operation into as few lines of code as possible. In fact, never go looking for the fewest lines of code -- that's obfuscation, not programming.



Related Topics



Leave a reply



Submit