I have created this search and replace program.
But I want to make changes to it, so I can do a search and replace for
multiple files at once.
Now, is there a way so I have
the option to select multiple files at once
from any folder or directory that I choose.
The code that helps me to select files using file dialog window is given below, but is giving errors. can you help me to correct it?
The FULL traceback error is :
Traceback <most recent call last>:
File "replace.py", line 24, in <module>
main()
File "replace.py", line 10, in main
file = tkFileDialog.askopenfiles(parent=root,mode='r',title='Choose a file')
File "d:\Python27\lib\lib-tk\tkFileDialog.py",line 163, in askopenfiles
ofiles.append(open(filename,mode))
IOError: [Errno 2] No such file or directory: u'E'
And here's the code: I finally got this code to work I changed 'file' to 'filez' and 'askopenfiles' to askopenfilenames'. and I was able to replace the word in my chosen file. the only thing is that it doesnt work when I choose 2 files. maybe I should add in a loop for it to work for multiple files. But, this was a kind of trial and error and I want to be able to really know why it worked. Is there a book or something that will help me to fully understand this tkinter and file dialog thing? anyways, I have changed the code below to show the working code now:
#replace.py
import string
def main():
#import tkFileDialog
#import re
#ff = tkFileDialog.askopenfilenames()
#filez = re.findall('{(.*?)}', ff)
import Tkinter,tkFileDialog
root = Tkinter.Tk()
filez = tkFileDialog.askopenfilenames(parent=root,mode='r',title='Choose a file')
#filez = raw_input("which files do you want processed?")
f=open(filez,"r")
data=f.read()
w1=raw_input("what do you want to replace?")
w2= raw_input("what do you want to replace with?")
print data
data=data.replace(w1,w2)
print data
f=open(filez,"w")
f.write(data)
f.close()
main()
EDIT: One of the replies below gave me an idea about file dialog window and now I am able to select multiple files using a tkinter window, but I am not able to go ahead with the replacing. it's giving errors.
I tried out different ways to use file dialog and the different ways are giving different errors. Instead of deleting one of the ways, I have just put a hash sign in front so as to make it a comment, so you guys are able to take a look and see which one would be better.
Maybe you should take a look at the glob module, it can make finding all files matching a simple pattern (such as *.txt) easy.
Or, easier still but less user-friendly, you could of course treat your input filename filez as a list, separating filenames with space:
for fn in filez.split():
# your code here, replacing filez with fn
You probably want to have a look at glob module.
An example that handles "*" in your input:
#replace.py
import string
import glob
def main():
filez = raw_input("which files do you want processed?")
filez_l = filez.split()
w1=raw_input("what do you want to replace?")
w2= raw_input("what do you want to replace with?")
# Handle '*' e.g. /home/username/* or /home/username/mydir/*/filename
extended_list = []
for filez in filez_l:
if '*' in filez:
extended_list += glob.glob(filez)
else:
extended_list.append(filez)
#print extended_list
for filez in extended_list:
print "file:", filez
f=open(filez,"r")
data=f.read()
print data
data=data.replace(w1,w2)
print data
f=open(filez,"w")
f.write(data)
f.close()
main()
I would rather use the command line instead of input.
#replace.py
def main():
import sys
w1 = sys.argv[1]
w2 = sys.argv[2]
filez = sys.argv[3:]
# ***
for fname in filez:
with open(fname, "r") as f:
data = f.read()
data = data.replace(w1, w2)
print data
with open(fname, "w") as f:
f.write(data)
if __name__ == '__main__':
main()
So you can call your program with
replace.py "old text" "new text" *.foo.txt
or
find -name \*.txt -mmin -700 -exec replace.py "old text" "new text" {} +
If you think of a dialog window, you could insert the following at the position with ***:
if not filez:
import tkFileDialog
import re
ff = tkFileDialog.askopenfilenames()
filez = re.findall('{(.*?)}', ff)
Why not put the program into a for-loop:
def main():
files = raw_input("list all the files do you want processed (separated by commas)")
for filez in files.split(','):
f=open(filez,"r")
data=f.read()
f.close()
w1=raw_input("what do you want to replace?")
w2= raw_input("what do you want to replace with?")
print data
data=data.replace(w1,w2)
print data
f=open(filez,"w")
f.write(data)
f.close()
main()
A good trick to open huge files line by line in python:
contents = map(lambda x: x.next().replace("\n",""),map(iter,FILES))
Related
it wont stop opening the program even if there is nothing in the txt file or nothing opens
import os
with open(r'file.txt'):
if "start" in 'file.txt':
os.startfile(r'C:\Program Files (x86)\Minecraft Launcher\MinecraftLauncher.exe')
Try something like this.
Currently your if statment is asking if "start" is in the string "file.txt" not in the file.
import os
GAME_LOCATION = r"C:\Program Files (x86)\Minecraft Launcher\MinecraftLauncher.exe"
with open("file.txt", 'r') as f:
line = f.readline()
print(line)
if "start" in line:
os.startfile(GAME_LOCATION)
else:
print("start is not in the file")
based on #loganRowe , you should put your code to this
import os
GAME_LOCATION = r'C:\"Program Files (x86)"\"Minecraft Launcher"\MinecraftLauncher.exe'
with open("file.txt", "r") as f:
line = f.readline()
if "start" in line:
os.system(GAME_LOCATION)
else:
print("start is not in the file")
IMPORTANT NOTE :
Make sure your file.txt is on the same directory as your .py file
Make sure the directory of the launcher is valid
"Program Files(x86)" is needed because if you don't have it, the console will read as Program Files(x86) which had an error of a space between the 2 word
I'm trying to run in Pycharm this programm :
# Chap02-03/twitter_hashtag_frequency.py
import sys
from collections import Counter
import json
def get_hashtags(tweet):
entities = tweet.get('entities', {})
hashtags = entities.get('hashtags', [])
return [tag['text'].lower() for tag in hashtags]
if __name__ == '__main__':
fname = sys.argv[1]
with open(fname, 'r') as f:
hashtags = Counter()
for line in f:
tweet = json.loads(line)
hashtags_in_tweet = get_hashtags(tweet)
hashtags.update(hashtags_in_tweet)
for tag, count in hashtags.most_common(20):
print("{}: {}".format(tag, count))
I want to run the programm twitter_hashtag_frequency.py in Pycharm using a json file stream_.jsonl as a parameter, this file is in the same directory as the programm. Can you show me how can I edit this code ? I tried several time, I did'nt succeed, I got this error :
fname = sys.argv[1]
IndexError: list index out of range
Thank you for your help.
If you run the file by pressing the green play button (next to Edit Configurations), you'll need to specify the argument in the configurations menu in Parameters. Enter stream_.jsonl in the text box.
Also double check that the working directory is set to the one containing both these files
there are multiple files in directory with extension .txt, .dox, .qcr etc.
i need to list out txt files, search & replace the text from each txt files only.
need to search the $$\d ...where \d stands for the digit 1,2,3.....100.
need to replace with xxx.
please let me know the python script for this .
thanks in advance .
-Shrinivas
#created following script, it works for single txt files, but it is not working for txt files more than one lies in directory.
-----
def replaceAll(file,searchExp,replaceExp):
for line in fileinput.input(file, inplace=1):
if searchExp in line:
line = line.replace(searchExp,replaceExp)
sys.stdout.write(line)
#following code is not working, i expect to list out the files start #with "um_*.txt", open the file & replace the "$$\d" with replaceAll function.
for um_file in glob.glob('*.txt'):
t = open(um_file, 'r')
replaceAll("t.read","$$\d","xxx")
t.close()
fileinput.input(...) is supposed to process a bunch of files, and must be ended with a corresponding fileinput.close(). So you can either process all in one single call:
def replaceAll(file,searchExp,replaceExp):
for line in fileinput.input(file, inplace=True):
if searchExp in line:
line = line.replace(searchExp,replaceExp)
dummy = sys.stdout.write(line) # to avoid a possible output of the size
fileinput.close() # to orderly close everythin
replaceAll(glob.glob('*.txt'), "$$\d","xxx")
or consistently close fileinput after processing each file, but it rather ignores the main fileinput feature.
Try out this.
import re
def replaceAll(file,searchExp,replaceExp):
for line in file.readlines():
try:
line = line.replace(re.findall(searchExp,line)[0],replaceExp)
except:
pass
sys.stdout.write(line)
#following code is not working, i expect to list out the files start #with "um_*.txt", open the file & replace the "$$\d" with replaceAll function.
for um_file in glob.glob('*.txt'):
t = open(um_file, 'r')
replaceAll(t,"\d+","xxx")
t.close()
Here we are sending file handler to the replaceAll function rather than a string.
You can try this:
import os
import re
the_files = [i for i in os.listdir("foldername") if i.endswith("txt")]
for file in the_files:
new_data = re.sub("\d+", "xxx", open(file).read())
final_file = open(file, 'w')
final_file.write(new_data)
final_file.close()
What I would like the final code to execute is read a string of names in a text document named, 'names.txt'. Then tell the program to calculate how many names there are in that file and display the amount of names. The code I have so far was meant to display the sum of the numbers in a text file, but it was close enough to the program I need now that I think I may be able to rework it to gather the amount of strings/names and display that instead of the sum.
Here is the code so far:
def main():
#initialize an accumulator.
total = 0.0
try:
# Open the file.
myfile = open('names.txt', 'r')
# Read and display the file's contents.
for line in myfile:
amount = float(line)
total += amount
# Close the file.
myfile.close()
except IOError:
print('An error occured trying to read the file.')
except ValueError:
print('Non-numeric data found in the file.')
except:
print('An error occured.')
# Call the main function.
main()
I am still really new to Python programming so please don't be too harsh on me. If anyone can figure out how to rework this to display the amount of numbers/names instead of the sum of numbers. I would greatly appreciate it. If this program cannot be reworked, I would be happy to settle for a new solution.
Edit: This it an example of what the 'names.txt' will look like:
john
mary
paul
ann
If you just want to count the lines in the file
# Open the file.
myfile = open('names.txt', 'r')
#Count the lines in the file
totalLines = len(myfile.readlines()):
# Close the file.
myfile.close()
fh = open("file","r")
print "%d lines"%len(fh.readlines())
fh.close()
or you could do
fh=open("file","r")
print "%d words"%len(fh.read().split())
fh.close()
All this is readily available information that is not hard to find if you put forth some effort...just getting the answers usually results in flunked classes...
Considering the names in your text files are delimited by line.
myfile = open('names.txt', 'r')
lstLines = myfile.read().split('\n')
dict((name,lstLines.count(name)) for name in lstLines)
This creates a dictionary of each name having its number of occurrence.
To search for the occurrence of perticular name such as 'name1' in the list
lstLines.count('name1')
Assuming names are splitted using whitespaces :
def main():
#initialize an accumulator.
total = 0.0
try:
# Open the file.
myfile = open('names.txt', 'r')
# Read and display the file's contents.
for line in myfile:
words = line.split()
total += len(words)
# Close the file.
myfile.close()
except IOError:
print('An error occured trying to read the file.')
except ValueError:
print('Non-numeric data found in the file.')
except:
print('An error occured.')
# Call the main function.
main()
Use with statement to open a file. It will close the file properly even if an exception occurred. You can omit the file mode, it is default.
If each name is on its own line and there are no duplicates:
with open('names.txt') as f:
number_of_nonblank_lines = sum(1 for line in f if line.strip())
name_count = number_of_nonblank_lines
The task is very simple. Start with a new code to avoid accumulating unused/invalid for the problem code.
If all you need is to count lines in a file (like wc -l command) then you could use .count('\n') method:
#!/usr/bin/env python
import sys
from functools import partial
read_chunk = partial(sys.stdin.read, 1 << 15) # or any text file instead of stdin
print(sum(chunk.count('\n') for chunk in iter(read_chunk, '')))
See also, Why is reading lines from stdin much slower in C++ than Python?
how to create file names from a number plus a suffix??.
for example I am using two programs in python script for work in a server, the first creates a file x and the second uses the x file, the problem is that this file can not overwrite.
no matter what name is generated from the first program. the second program of be taken exactly from the path and file name that was assigned to continue the script.
thanks for your help and attention
As far as I can understand you, you want to create a file with a unique name in one program and pass the name of that file to another program. I think you should take a look at the tempfile module, http://docs.python.org/library/tempfile.html#module-tempfile.
Here is an example that makes use of NamedTemporaryFile:
import tempfile
import os
def produce(text):
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
f.write(text)
return f.name
def consume(filename):
try:
with open(filename) as f:
return f.read()
finally:
os.remove(filename)
if __name__ == '__main__':
filename = produce('Hello, world')
print('Filename is: {0}'.format(filename))
text = consume(filename)
print('Text is: {0}'.format(text))
assert not os.path.exists(filename)
The output is something like this:
Filename is: /tmp/tmpp_iSrw.txt
Text is: Hello, world