0

Using Below given python script, I am trying to copy a text file and trying to create 10 copies of the same file as shown below:

logs1.txt
logs2.txt
.
.
logs10.txt

Basically i need to increment only the number present in destination text file name.

I have tried using "for loop" with range command. But I dont know how to increment a number inside a cp command.

#/usr/bin/env python
import subprocess

class RunCmd(object):
    def cmd_run(self, cmd):
        self.cmd = cmd
        subprocess.call(self.cmd, shell=True)


a = RunCmd()
a.cmd_run('cp /sh/awlog/Logs_new_1.txt /sh/logs/logs1.txt')
3
  • 2
    Looks like a convoluted way of doing something simple. Why are you creating a class to do this? Take a look at shutil module. Also, learn basics of python string operations. Commented Jan 3, 2019 at 10:16
  • there are several ways to achieve that. You could have a for loop in range(10) which run the same cmd command and update the name of the target file by concatenate the num to the string. '/sh/logs/logs' + num + '.txt' Commented Jan 3, 2019 at 10:19
  • Agreed, and if you really want that, at least associate the command in the RunCmd constructor, e.g. gist.github.com/fcracker79/d971c2a903a08c80ee8148ad00af667a Commented Jan 3, 2019 at 10:19

5 Answers 5

4

It should be as simple as

import shutil

for i in range(10):
    shutil.copyfile('/path/to/source/file','/destination/path/logs'+str(i+1)+'.txt')

There's no need to create a class to carry out such simple functionality. Also, copying files can be done using the shutil module directly rather than creating a subprocess to do so.

More information about shutil: How do I copy a file in Python?

Edit:

alternate code as per Bruno's suggestions:

import shutil

for i in range(1,11):
    shutil.copyfile('/path/to/source/file','/destination/path/logs{}.txt'.format(i))
Sign up to request clarification or add additional context in comments.

4 Comments

You should use string formatting instead of string concatenation, and range() can take a start argument so you don't need the i+1 at all.
@brunodesthuilliers at that point it's pretty much more about looks than anything else but yeah, that is some alternate syntax. (Unless you really need to worry about performance, of course)
it's not "pretty much about looks than anything else" but about writing readable idiomatic code. Readiblity is highly valued by python programmers.
The difference in readability between these two particular examples is opinion-based. Somebody might see the 10 as clearly showing that there is exactly 10 iterations. Others might prefer the other syntax. Also, in this situation, as there isn't a lot of different variables to be concatenated, you could make a case for either concatenation or using format. In any case, I've provided the alternate syntax you suggested as well.
4

The shutil module offers a number of high-level operations on files and collections of files. In particular, functions are provided which support file copying and removal.

import shutil

for i in range(10):
    shutil.copyfile(
        "/sh/awlog/Logs_new_1.txt",
        "/sh/logs/logs{}.txt".format(i+1)
    )

1 Comment

@RoadRunner No.
2

Since the a.cmd_run command-argument contains a string, you can just change this string in a while-loop.

i = 1
while i < 11:
    string = 'cp /sh/ec_rawlog/Logs_new_1.txt /sh/logs/logs%s.txt' % i
    a = RunCmd()
    a.cmd_run(string)
    i += 1

Comments

1

You should use string formatting

templ = 'cp /sh/ec_rawlog/Logs_new_{0}.txt /sh/logs/logs{0}.txt'
for num in range(1,11):
    print(templ.format(num))

output

cp /sh/ec_rawlog/Logs_new_1.txt /sh/logs/logs1.txt
cp /sh/ec_rawlog/Logs_new_2.txt /sh/logs/logs2.txt
cp /sh/ec_rawlog/Logs_new_3.txt /sh/logs/logs3.txt
cp /sh/ec_rawlog/Logs_new_4.txt /sh/logs/logs4.txt
cp /sh/ec_rawlog/Logs_new_5.txt /sh/logs/logs5.txt
cp /sh/ec_rawlog/Logs_new_6.txt /sh/logs/logs6.txt
cp /sh/ec_rawlog/Logs_new_7.txt /sh/logs/logs7.txt
cp /sh/ec_rawlog/Logs_new_8.txt /sh/logs/logs8.txt
cp /sh/ec_rawlog/Logs_new_9.txt /sh/logs/logs9.txt
cp /sh/ec_rawlog/Logs_new_10.txt /sh/logs/logs10.txt

4 Comments

@RoadRunner the fact that the OP will need to pass the formatted string to a.cmd_run() is obvious enough.
@brunodesthuilliers Fair enough, I've removed my comment. I'm just suggesting a reason to why this answer was probably downvoted.
@RoadRunner Fair enough too ;-)
Also, OP question is effectively how to increment the number within the string. Most of the other answers are more focused on how to copy the file.
0

The other answers are good, but you can also do this the old fashioned way:

# Open main file
with open("/sh/awlog/Logs_new_1.txt") as f_in:

    # Read in text
    file_str = f_in.read()

    # Iterate 1 - 10
    for i in range(1, 11):

        # Open new file to write to with number
        with open("/sh/logs/logs%d.txt" % i, mode="w") as f_out:
            f_out.write(file_str)

You can simply iterate over range(1, 11) to get the numbers 1 - 10, excluding 11. You can have a look at range() for behavior specifics.

Addtionally, as pointed out in the other answers, the good thing about shutil.copyfile() is that it avoids the need to open files, as shown above, and you can copy the content over directly with no issues.

Having said this, the source code does still open files under the hood, so I guess that's something to consider.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.