How to Modify a Text File

How to edit a text file in my terminal

Open the file again using vi. and then press the insert button to begin editing it.

How to edit a text file?

Script below will build new file and you can set number of lines that you want to create.

First all lines are read from input file and then it writes number of lines you set to new file.

list_emitter can infinitely yield items from given list, so you can just adjust output_lines_count variable to make your output file even bigger.

def list_emitter(l):
"""This generator will endlessly yield items from given list."""
while True:
for item in l:
yield item


with open('file_1.txt') as input_file:
lines = input_file.readlines() # Create list of lines

with open('output_file.txt', 'w') as output_file:
output_lines_count = 10 # Set how many output lines you want
for counter, line in enumerate(list_emitter(lines)):
if counter == output_lines_count:
break
first, second, third = line.strip().split() # Parse line
output_file.write('{}, {} {}\n'.format(counter+1, second, third))

How to edit a text file at a specific line or location

I'd use regular expressions to match and replace text inside your file

import re

def search_write_in_file(file_name, string_to_search, description):
with open(file_name, 'r+') as file_obj:
text = file_obj.read()
new_text = re.sub(string_to_search,r"\1 {0}\n".format(description),text)
with open(file_name, 'w') as file_obj:
file_obj.write(new_text)
print(new_text)

if __name__ == '__main__':
search_write_in_file('text_to_edit.txt',r'(DATATYPE2;\n)',"test2")
search_write_in_file('text_to_edit.txt',r'(DATATYPE4;\n)',"test4")

This will update the existing file to be

VAR_GROUP
Var1 : DATATYPE1;(Description Var)
Var2 : DATATYPE2; test2
Var3 : DATATYPE3;(Description Var3)
Var4 : DATATYPE4; test4
END_GROUP

How to edit a specific line of a txt file in C

What you are missing is somewhat conceptual, and somewhat related to fopen. When you think about opening a file with fopen, you need to pay particular attention to the effect of the file modes. If you look carefully at the man page regarding either "w" or "w+". In both cases the existing file is truncated. To 0-length in the case of "w".

To avoid this issue, one approach is to read the entire file into a buffer and then make changes to the buffer, writing the modified buffer back to the original filename. This avoids the possibility to attempting to insert/delete bytes without rewriting the remainder of the file.

To handle reading the file into a buffer, the link posted overwriting a specific line on a text file?, provides a roadmap to changing a single line in a file. Your case is different. You want to find/replace All occurrences of a particular pattern. (that is where the truncation issue posses challenges) However much of the solution there can be applied to reading the file itself into a buffer. Specifically the use of fseek and ftell.

Using fseek and ftell provides a simply way to determine the size (or length) of the file that can then be used to allocate space to hold the entire file in memory. Below is one approach to a simple function that takes the address of a character pointer and a file pointer, then using fseek and ftell allocates the required memory to hold the file and then reads the file into the buffer (filebuf) in a single operation with fread. The buffer is filled, in place, and also returned. A pointer to the file length fplen is passed to the function so the length is made available back in the calling function (main() in this case). Returning a pointer to the buffer on success (NULL otherwise) will allow assignment of the return, if desired, and a way to determine success/failure of the read:

char *read_file_into_buf (char **filebuf, long *fplen, FILE *fp)
{
fseek (fp, 0, SEEK_END);
if ((*fplen = ftell (fp)) == -1) { /* get file length */
fprintf (stderr, "error: unable to determine file length.\n");
return NULL;
}
fseek (fp, 0, SEEK_SET); /* allocate memory for file */
if (!(*filebuf = calloc (*fplen, sizeof *filebuf))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return NULL;
}

/* read entire file into filebuf */
if (!fread (*filebuf, sizeof *filebuf, *fplen, fp)) {
fprintf (stderr, "error: file read failed.\n");
return NULL;
}

return *filebuf;
}

Once you have the file in memory, the second piece of the puzzle is simply to scan through the buffer and make the replacements you need. Here there are a number of different tweaks you can apply to optimize the search/replace, but the following is just a straight forward basic search/replace where the only optimization attempt is a comparison of the starting character before using the normal string.h string comparison functions to check for your specified search string. The function returns the number of replacements made so you can determine whether a write out to the original filename is required:

unsigned find_replace_text (char *find, char *rep, char *buf, long sz)
{
long i;
unsigned rpc = 0;
size_t j, flen, rlen;

flen = strlen (find);
rlen = strlen (rep);

for (i = 0; i < sz; i++) {
/* if char doesn't match first in find, continue */
if (buf[i] != *find) continue;

/* if find found, replace with rep */
if (strncmp (&buf[i], find, flen) == 0) {
for (j = 0; buf[i + j] && j < rlen; j++)
buf[i + j] = rep[j];
if (buf[i + j])
rpc++;
}
}

return rpc;
}

Putting all the pieces together in a short example program using your sample data could be written as follows. The program expects the filename as the first argument (or it will read from stdin and write to stdout by default if no filename is given). There are always additional validation checks you can include as well:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

char *read_file_into_buf (char **filebuf, long *fplen, FILE *fp);
unsigned find_replace_text (char *find, char *rep, char *buf, long sz);

int main (int argc, char **argv) {

char *srchstr = "400,300";
char *repstr = "400,300: (000,000,000) #000000";
char *filebuf = NULL;
long int fplen = 0;
FILE *fp = NULL;

/* open file for reading (default stdin) */
fp = argc > 1 ? fopen (argv[1], "r") : stdin;

if (!fp) { /* validate file open */
fprintf (stderr, "error: file open failed '%s'\n", argv[1]);
return 1;
}

if (!read_file_into_buf (&filebuf, &fplen, fp)) return 1;
if (fplen < 1 || fplen >= INT_MAX) { /* validate file length */
fprintf (stderr, "error: length of file invalid for fwrite use.\n");
return 1;
}
if (fp != stdin) fclose (fp);

/* find/replace text in filebuf */
if (!find_replace_text (srchstr, repstr, filebuf, fplen)) {
printf ("no replacements made.\n");
return 0;
}

/* open file for writing (default stdout) */
fp = argc > 1 ? fopen (argv[1], "w") : stdout;

if (!fp) { /* validate file open */
fprintf (stderr, "error: file open failed '%s'\n", argv[1]);
return 1;
}

/* write modified filebuf back to filename */
if (fwrite (filebuf, sizeof *filebuf, (size_t)fplen, fp) != (size_t)fplen) {
fprintf (stderr, "error: file write failed.\n");
return 1;
}
if (fp != stdout)
if (fclose (fp) == EOF) {
fprintf (stderr, "error: fclose() returned EOF\n");
return 1;
}

free (filebuf);

return 0;
}

Just include the functions at the bottom of the file. You can then:

Compile

gcc -Wall -Wextra -O3 -o bin/fread_file fread_file.c

(or use the equivalent compile string with your compiler)

Input File

$ cat dat/rbgtst.txt
400,280: (234,163,097) #EAA361
400,300: (255,255,255) #FFFFFF
400,320: (064,101,160) #4065A0
400,340: (220,194,110) #DCC26E

Use/File After Replacement

$ ./bin/fread_file dat/rbgtst.txt
$ cat dat/rbgtst.txt
400,280: (234,163,097) #EAA361
400,300: (000,000,000) #000000
400,320: (064,101,160) #4065A0
400,340: (220,194,110) #DCC26E

or reading from stdin writing to stdout:

$ ./bin/fread_file <dat/rbgtst.txt
400,280: (234,163,097) #EAA361
400,300: (000,000,000) #000000
400,320: (064,101,160) #4065A0
400,340: (220,194,110) #DCC26E

Memory/Error Check

In any code your write that dynamically allocates memory, you have 2 responsibilites regarding any block of memory allocated: (1) always preserves a pointer to the starting address for the block of memory so, (2) it can be freed when it is no longer needed.

It is imperative that you use a memory error checking program to insure you haven't written beyond/outside your allocated block of memory, attempted to read or base a jump on an unintitialized value and finally to confirm that you have freed all the memory you have allocated.

For Linux valgrind is the normal choice. There are many subtle ways to misuse a new block of memory. Using a memory error checker allows you to identify any problems and validate proper use of of the memory you allocate rather than finding out a problem exist through a segfault. There are similar memory checkers for every platform. They are all simple to use, just run your program through it. E.g.:

$ valgrind ./bin/fread_file dat/rbgtst.txt
==13768== Memcheck, a memory error detector
==13768== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==13768== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==13768== Command: ./bin/fread_file dat/rbgtst.txt
==13768==
==13768==
==13768== HEAP SUMMARY:
==13768== in use at exit: 0 bytes in 0 blocks
==13768== total heap usage: 3 allocs, 3 frees, 2,128 bytes allocated
==13768==
==13768== All heap blocks were freed -- no leaks are possible
==13768==
==13768== For counts of detected and suppressed errors, rerun with: -v
==13768== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

You want to confirm All heap blocks were freed -- no leaks are possible and ERROR SUMMARY: 0 errors from 0 contexts (ignore the suppressed note which simply relates to missing debug symbol files not installed on my system)

Look over the code and understand what it is doing. This isn't presented as the only way of doing what you are attempting to do, but it is presented as an example of how to approach the problem while avoiding a number of pitfalls inherent in trying to change a line-at-a-time in an existing file utilizing offsets and a number of reads/writes to the file. Let me know if you have questions.

How to edit a text file using MATLAB?

As the comment above suggested there isn't such a function built into MATLAB. Writing your own function/script is the best option. Below is a script that reads the second column of the text file and creates the first column of the text file named Column_1. The Data is then written written to a text file using the fprintf() function.

File_Name = "Text.txt";
Format_File(File_Name);

%Function definition%
function [] = Format_File(File_Name)

T = readtable(File_Name);

Column_1 = 1:height(T);
Column_2 = ((T{:,2}));

Data(1,:) = Column_1;
Data(2,:) = Column_2;

fileID = fopen('Text.txt','w');
fprintf(fileID,'%d %.1f\n',Data);
fclose(fileID);

end


Input: Text.txt

"1981-02-01",15.3
"1981-02-02",18.8
"1981-02-03",21.9
"1981-02-04",19.9

Output: Text.txt

1   15.3
2 18.8
3 21.9
4 19.9

Ran using MATLAB R2019b



Related Topics



Leave a reply



Submit