1

So as most of us are thinking it's a duplicate which is not, so what I'm trying to achieve is let's say there is a Master string like the below and couple of files mentioned in it then we need to open the files and check if there are any other files included in it, if so we need to copy that into the line where we fetched that particular text.

Master String:

Welcome
How are you
file.txt
everything alright
signature.txt
Thanks

file.txt

ABCD
EFGH
tele.txt

tele.txt

IJKL

signature.txt

SAK

Output:

Welcome
How are you
ABCD
EFGH
IJKL
everything alright
SAK
Thanks

for msplitin [stext.split('\n')]:
            for num, items in enumerate(stext,1):
                if items.strip().startswith("here is") and items.strip().endswith(".txt"):
                       gmsf = open(os.path.join(os.getcwd()+"\txt", items[8:]), "r")
                        gmsfstr = gmsf.read()
                        newline = items.replace(items, gmsfstr)

How to join these replace items in the same string format.

Also, any idea on how to re-iterate the same function until there are no ".txt". So, once the join is done there might be other ".txt" inside a ".txt.

Thanks for your help in advance.

IAmHomes
  • 513
  • 2
  • 11
  • 20

3 Answers3

1

You can try:

s = """Welcome
How are you
here is file.txt
everything alright
here is signature.txt
Thanks"""

data = s.split("\n")
match = ['.txt']
all_matches = [s for s in data if any(xs in s for xs in match)]

for index, item in enumerate(data):
    if item in all_matches:
        data[index] ="XYZ"

data = "\n".join(data)
print data

Output:

Welcome
How are you
XYZ
everything alright
XYZ
Thanks

Added new requirement:

def file_obj(filename):
        fo = open(filename,"r")
        s = fo.readlines()
        data = s.split("\n")
        match = ['.txt']
        all_matches = [s for s in data if any(xs in s for xs in match)]
        for index, item in enumerate(data):
                if item in all_matches:
                        file_obj(item)
                        data[index] ="XYZ"

        data = "\n".join(data)
        print data
file_obj("first_filename") 
Harsha Biyani
  • 7,049
  • 9
  • 37
  • 61
  • added.. I replaced both .txt file by XYZ.. You can replace as your wish.. I did this because it will handle last amount of data.. no need to replace each & every string.. – Harsha Biyani Aug 23 '16 at 06:37
  • I think, the requirement is to open file - search string - if matched then replace. The demo code SAK has posted contains the operations like check if file exist, read file contents etc – Dinesh Pundkar Aug 23 '16 at 06:55
  • 2
    @HarshaBiyani Thanks Harsha for your help. – IAmHomes Aug 23 '16 at 07:32
  • 2
    @DineshPundkar - And I changed the code where it refers to open for reading files. Thanks for your help guys – IAmHomes Aug 23 '16 at 07:32
  • @HarshaBiyani also, any idea on how to re-iterate the same function until there are no ".txt". So, once the join is done there might be other ".txt" inside a ".txt.hope i'm not confusing. – IAmHomes Aug 23 '16 at 08:22
  • so it means, inside "here is file.txt" file, there might be again .txt ?? – Harsha Biyani Aug 23 '16 at 08:26
  • @HarshaBiyani yes Harsha – IAmHomes Aug 23 '16 at 08:36
  • @HarshaBiyani thanks for the idea, i think what i was telling is more like an iteration, there could be a bunch of txt's and in that again a bunch. I know I might be just creating a mess around here. But just a thought. – IAmHomes Aug 23 '16 at 12:39
1

A recursive approach that works with any level of file name nesting:

from os import linesep

def get_text_from_file(file_path):
    with open(file_path) as f:
        text = f.read()
        return SAK_replace(text)

def SAK_replace(s):
    lines = s.splitlines()
    for index, l in enumerate(lines):
        if l.endswith('.txt'):
            lines[index] = get_text_from_file(l)
    return linesep.join(lines)
Craig Burgler
  • 1,749
  • 10
  • 19
  • @SAK my pleasure :) I think you checkmarked the wrong answer tho :) – Craig Burgler Aug 23 '16 at 17:10
  • i found out another problem, so when there is 2 level files i.e. file - file - file then there is an error "cannot concatenate 'str' and 'NoneType' objects" – IAmHomes Aug 23 '16 at 17:15
  • one sec lemme try it – Craig Burgler Aug 23 '16 at 17:18
  • fixed some line separator issues, tested it up to file-file-file-file so should be good for any level. try it now and lemme know – Craig Burgler Aug 23 '16 at 17:36
  • @criagBurgler no luck yet, here is the error code - m.txt D:/k/m.txt [Errno 22] invalid mode ('rb') or filename: u'D:/k/m.txt\r\n' cannot concatenate 'str' and 'NoneType' objects Traceback (most recent call last): File "D:\Installation\Python27\Lib\site-packages\gevent\greenlet.py", line 522, in run result = self._run(*self.args, **self.kwargs) File "D:\k\t.py", line 72, in start result = self.do_as(s) File "D:\k\core\tasks.py", line 159, in do_work replaced = '\n'.join(lines) TypeError: sequence item 31: expected string or Unicode, NoneType found – IAmHomes Aug 23 '16 at 18:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/121660/discussion-between-craig-burgler-and-sak). – Craig Burgler Aug 23 '16 at 18:28
  • @craigBurgler- I fixed the issue thanks a lot for your help. – IAmHomes Aug 23 '16 at 18:49
  • I changed the code so that line separators are handle by Python – Craig Burgler Aug 24 '16 at 00:26
0

We can create temporary file object and keep the replaced line in that temporary file object and once everything line is processed then we can replace with the new content to original file. This temporary file will be deleted automatically once its come out from the 'with' statement.

import tempfile
import re

file_pattern = re.compile(ur'(((\w+)\.txt))')
original_content_file_name = 'sample.txt'
"""
sample.txt should have this content.

Welcome
How are you
here is file.txt
everything alright
here is signature.txt
Thanks
"""
replaced_file_str = None


def replace_file_content():
    """
    replace the file content using temporary file object.
    """

    def read_content(file_name):
        # matched file name is read and returned back for replacing.
        content = ""
        with open(file_name) as fileObj:
            content = fileObj.read()
        return content

    # read the file and keep the replaced text in temporary file object(tempfile object will be deleted automatically).
    with open(original_content_file_name, 'r') as file_obj, tempfile.NamedTemporaryFile() as tmp_file:
        for line in file_obj.readlines():
            if line.strip().startswith("here is") and line.strip().endswith(".txt"):
                file_path = re.search(file_pattern, line).group()

                line = read_content(file_path) + '\n'
            tmp_file.write(line)
        tmp_file.seek(0)
        # assign the replaced value to this variable
        replaced_file_str = tmp_file.read()

    # replace with new content to the original file
    with open(original_content_file_name, 'w+') as file_obj:
        file_obj.write(replaced_file_str)

replace_file_content()
Sathish
  • 51
  • 2