0

So I'm trying to create a Python script that will look through *.styles and *.layout files and replace specific strings in those files. I've tried a number of things, but I can't figure out what I should be doing, and even looking at other code samples online just makes it even more confusing to understand.

here's what I have in my code currently;

#!/usr/bin/python3
# coding: utf-8

import os
import sys
import fileinput

f1 = open ('*.styles', 'r') # read *.styles
f2 = open ('*.styles', 'w') # write *.styles
f3 = open ('*.layout', 'r') # read *.layout
f4 = open ('*.layout', 'w') # write *.layout
for line in f1:
    f2.write(line.replace('font-size=15','font-size=12'))  # replace string for
    f2.write(line.replace('font-size=14','font-size=12'))  # files in *.styles
    f2.write(line.replace('font-size=18','font-size=14'))
    f2.write(line.replace('font-size=30','font-size=18'))
    f2.write(line.replace('font-size=36','font-size=18'))
    f2.write(line.replace('font-size=16','font-size=12'))
    f2.write(line.replace('font-size=26','font-size=16'))
    f2.write(line.replace('font-size=48','font-size=20'))
    f2.write(line.replace('font-size=28','font-size=16'))
    f2.write(line.replace('font-size=17','font-size=14'))
    f2.write(line.replace('font-size=21','font-size=14'))
f1.close()
f2.close()

for line in f3:
    f4.write(line.replace('font-size=15','font-size=12'))  # replace string for
    f4.write(line.replace('font-size=14','font-size=12'))  # files in *.layout
    f4.write(line.replace('font-size=18','font-size=14'))
    f4.write(line.replace('font-size=30','font-size=18'))
    f4.write(line.replace('font-size=36','font-size=18'))
    f4.write(line.replace('font-size=16','font-size=12'))
    f4.write(line.replace('font-size=26','font-size=16'))
    f4.write(line.replace('font-size=48','font-size=20'))
    f4.write(line.replace('font-size=28','font-size=16'))
    f4.write(line.replace('font-size=17','font-size=14'))
    f4.write(line.replace('font-size=21','font-size=14'))
f3.close()
f4.close()

print ("\n\n ## Done!\n\n")
sys.exit(0)

I did want to include a "Would you like to commit changes? [Y/n]" with a simple Yes/No user input answer, but that got a little too complicated to figure out with While True: and While False: statements.

When this code is test run on the files I want to test this on it just turns an error saying;

line 8, in <module>
    f1 = open ('*.styles', 'r') # read *.styles
FileNotFoundError: [Errno 2] No such file or directory: '*.styles'

I just want to be able to run from command line like so;

$ string_search.py .

so it changes all files in the current directory that contains *.styles and *.layout files in that directory so you don't have to specify an actual directory, just in current directories and folders.

  • Possible duplicate of [Get a filtered list of files in a directory](http://stackoverflow.com/questions/2225564/get-a-filtered-list-of-files-in-a-directory) – Two-Bit Alchemist Jul 13 '16 at 15:23
  • 2
    I don't know why you included all this information about string searching and while loops and everything else when your question boils down to one line of code causing an issue. Please try to stick to one question per post and use a *minimal* verifiable example. – Two-Bit Alchemist Jul 13 '16 at 15:24
  • @Two-BitAlchemist - You're missing the point, and this is one question. The main question is How do I get Python to search through every file specified and replace the specified strings within those certain files with the new string I want to replace them with. It comes down to a quick easy solution that can be done to many files with a quick commit change, saving the time having to go through each file individually. –  Jul 13 '16 at 15:32
  • @user94959: You can get useful answers more easily if you split your question: 1. How to get a list of matching files in Python? 2. How to do string replacement on a single file in Python, writing back the results to the same file? – pts Jul 13 '16 at 15:38
  • @user94959 Actually you're missing the point. All your other code works. What doesn't work is what you're trying to do in order to process several files matching a glob pattern. That's why you got 3 answers that have nothing to do with string replacement. – Two-Bit Alchemist Jul 13 '16 at 19:42
  • @Two-BitAlchemist No actually, they've actually proved to be little bit helpful to what I'm looking to do. And no, the rest of my code does not work. –  Jul 13 '16 at 23:20

3 Answers3

1

As Scott Hunter wrote, open opens a single file. You need to get a list of matching files, and call open separately for each of them, in a loop. Here is how to do it.

Create a function which processes a single file:

def process_file(filename):
  print(filename)
  # ... open(filename) ...
  # ... open(filename, 'w') ...

Then call the function like this:

import glob
for filename in glob.glob('*.styles'):
  process_file(filename)

Or like this, for recursive enumeration of directories and files:

import os
for dirpath, dirnames, filenames in os.walk('.'):
  for filename in filenames:
    # Instead of .endswith, you can use the fnmatch module to match on '*.styles'.
    if filename.endswith('.styles'):
      process_file(os.path.join(dirpath, filename))
pts
  • 80,836
  • 20
  • 110
  • 183
0

open opens a single file; you seem to be trying to use it to open a collection of files that match a pattern. Perhaps you want to look at os.walk to traverse a directory of files, so you can individually process each.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
-1

I had to do something like that. I managed with fileinput.input something like : First i would iterate on the files and then modify them :

for current_path, dirs, files in os.walk(Your_Path_With_Files)):
            for file in files:
                if file.endswith('.styles'):
                   #here you store the file path somewhere
                   #I'm not 100% the exact way to have the full path,
                   # but it's with os.path.join() to have a clean path
                   #list_path_styles_files 

then when you have all the paths from the files you need to modify :

for the_path in list_path_styles_files:
        for line in fileinput.input(the_path, inplace=1):
                line = line.replace('font-size=15','font-size=12')
                line = ...
                ...
                print line 

This will read the lines one by one, then modify the line the way you want, then put it in the file

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
pwnsauce
  • 416
  • 4
  • 14