The following code generates a json file, however, I need to get rid of the enumerator element in the output (i.e. "1":, "2":, etc.). It looks like a dumb question but I'm totally confused!
The output looks like this:
{
"1": {
"found": "Alaska",
"resolved as": " alaska",
"gazetteer": " {com.novetta.clavin.gazetteer.LazyAncestryGeoName#59b62d}",
"position": " 795",
"confidence": " 1.000000",
"fuzzy": " false",
"lon": " -150.00028",
"lat": " 64.00028"
}, ...
And here is the code:
import json
filename = 'output.txt'
dict1 = {}
fields = ['found', 'resolved as', 'gazetteer', 'position', 'confidence', 'fuzzy', 'lon', 'lat' ]
with open(filename) as fh:
l = 1
for line in fh:
# reading line by line from the text file
description = list( line.strip().split(','))
# for output see below
print(description)
# for automatic creation of id for each employee
sno = '' + str(l)
# loop variable
i = 0
# intermediate dictionary
dict2 = {}
while i<len(fields):
# creating dictionary for each employee
dict2[fields[i]]= description[i]
i = i + 1
# appending the record of each employee to
# the main dictionary
dict1[sno]= dict2
l = l + 1
# creating json file
out_file = open("test2.json", "w")
json.dump(dict1, out_file, indent = 4)
out_file.close()
To get rid of the enumerator, there should only be one dictionary. Here is the new code which converts a text file to json:
import json
filename = 'output.txt'
fields = ['found', 'resolved as', 'gazetteer', 'position', 'confidence', 'fuzzy',
'lon', 'lat' ]
dic1 = {}
with open(filename) as fh:
for line in fh:
# reading line by line from the text file
description = list( line.strip().split(','))
print(description)
for lines in description:
for key in fields:
for value in description:
dic1[key] = value
description.remove(value)
break
#print (str(dic1))
json_string = json.dumps(dic1)
print(json_string)
Now, the output in the json file looks like this (without the enumerator (i.e. key):
{"found": "Alaska", "resolved as": " alaska", "gazetteer": " {com.novetta.clavin.gazetteer.LazyAncestryGeoName#59b62d}", "position": " 56332", "confidence": " 1.000000", "fuzzy": " false", "lon": " -150.00028", "lat": " 64.00028"}
Related
I have a file with multiple objects like this:
{
name: (sindey, crosby)
game: "Hockey"
type: athlete
},
{
name: (wayne, gretzky)
game: "Ice Hockey"
type: athlete
}
...and I'd like to convert them to JSON format and output this:
[
{
"name": "(sindey, crosby)",
"game": "Hockey",
"type": "athlete"
},
{
"name": "(wayne, gretzky)",
"game": "Ice Hockey",
"type": "athlete"
}
]
If the input was in this format,
name: (sidney, crosby) | game:"Hockey" | type:athlete
name: (wayne, gretzky) | game:"Ice Hockey" | type:athlete
I could implement using json dump with list and dict and it gives me the desired output
import json
f = open("log.file", "r")
content = f.read()
splitcontent = content.splitlines()
d = []
for v in splitcontent:
l = v.split(' | ')
d.append(dict(s.split(':',1) for s in l))
with open("json_log.json", 'w') as file:
file.write((json.dumps(d, indent=4, sort_keys= False)))
How can I reformat this code to convert my input to JSON format?
With slight changes on the answer given by #sarah Messer. Changes involved
lines without the : separator skipped
Try this
import json
f = open("log.file", "r")
content = f.read()
splitcontent = content.splitlines()
d = []
appendage = {}
for line in splitcontent:
if ('}' in line) or ('{' in line) or ('{' in line) or ('}' in line):
# Append a just-created record and start a new one
if appendage:
d.append(appendage)
appendage = {}
continue
key, val = line.split(':')
if val.endswith(','):
# strip a trailing comma
val = val[:-1]
print(val)
# if val == "":
# pass
# else:
appendage[key] = val
with open("json_log.json", 'w') as file:
file.write((json.dumps(d, indent=4, sort_keys=False)))
Something like this will probably work for most cases - you just have to handle the lines with curly braces separately from the lines with data:
import json
f = open("log.file", "r")
content = f.read()
splitcontent = content.splitlines()
d = []
appendage = {}
for line in splitcontent:
if ('}' in line) or ('{' in line):
# Append a just-created record and start a new one
if appendage:
d.append(appendage)
appendage ={}
else:
key, val = line.split(':',1)
if val.endswith(','):
# strip a trailing comma
val = val[:-1]
appendage[key] = val
with open("json_log.json", 'w') as file:
file.write((json.dumps(d, indent=4, sort_keys= False)))
I might also have some typos in there...
I have a script for a video game modification that has to be repeated 3544 times.
country_event = {
id = 5893X
title = "Aquire $PROVINCENAME$"
desc = "$COUNTRY$ is surrendering a province to us."
picture = "administration"
trigger = {
has_country_flag = won_acquire_prov
NOT = { has_country_flag = prov_treaty }
any_country = {
limit = {
truce_with = THIS
NOT = {
X = {
owned_by = THIS
}
}
}
}
}
option = {
name = "Take $PROVINCENAME$"
X = {
secede_province = THIS
}
}
option = {
name = "We don't want $PROVINCENAME$"
}
option = {
name = "End Province arbitration"
set_country_flag = prov_treaty
}
}
The goal is to replace "X" with a number ranging from 1 to 3544 for each number there will be another "country_event". But I am not sure how to do this.
I have tried using a python script:
infile = open("provids.txt", "r")
outfile = open("0_provs_event.txt","w")
for line in infile:
if len(line) > 5:
if line[5] == "=":
prov = line.split("/")[1].split(".")[0]
if prov != "REB":
#^^^ Code does not change file if above is removed
newline = "country_event = { id = 5893" + prov + "title = Aquire $PROVINCENAME$ desc = $COUNTRY$ is surrendering a province to us. picture = administration trigger = { has_country_flag = won_aquire_prov NOT = { has_country_flag = prov_treaty } any_country = { limit = { truce_with = THIS NOT = {" + tag + "= { owned_by = THIS } } } } } option = { name = Take $PROVINCENAME$ " + prov + " = { secede_province = THIS } } option = { name = We don't want $PROVINCENAME$ } option = { name = End Province arbitration set_country_flag = prov_treaty } } \n"
outfile.write(newline)
infile.close()
outfile.close()
I haven't been able to get it to work. It just makes the file and does nothing else.
The main issue is how you're reading in infile
When you call open, python will open the file as '_io.TextIOWrapper' which is a class that contains metadata about the file among other things. If you want the text of the file as a list of strings, where each string is a line of the file (which appears to be what you want), you then need to read the file. This can be done using infile.read() if you want the whole this as a single string, or infile.readlines() if you want each line to be an element of a list
My preferred way of reading in files in python is as follows:
# Setup file paths, and something to store your output which will be written to outfile_path
infile_path = "path_to_infile"
outfile_path = "path_to_outfile"
outfile = []
with open(infile_path, 'r') as f: # Open infile_path into f as a readable object
infile = f.readlines() # Read through f and place each line as an element in a list
for line in infile:
# do stuff, append lines to outfile
outfile = "\n".join(outfile) # Turn the list outfile into a string with character returns between each line
with open(outfile_path, 'w') as f: # Open outfile_path into f as a writable object
f.write(outfile) # Write out the string outfile to f
The advantage of the with open version is you don't need to remember to close the file afterwards, that automatically happens after the with block (after the unindent in the code)
Hi I am currently trying to merge multiple json files with the same structure to one json file.
Appending works but it is adding the parentheses [] to the new file with the resulting json file.
The code is getting the main json filename.txt and adding filename_1.txt to find it, it will open it, open filename_2.txt get a list and adding it to filename_1.txt
Result Json file:
{
"DateTimeUTC": "/Date(1590149927318)/",
"Journals": [
{
"JournalNumber": 1,
"JournalLines": [
{
"JournalLineID": "a",
"AccountID": "1a"
}
]
},
[
{
"JournalDate": "/Date(1415836800000+0000)/",
"JournalNumber": 2,
"JournalLines": [
{
"JournalLineID": "a",
"AccountID": "2a"
}
]
}
]
]
}
and this is the code I am using to merge the json file.
import json
def ConcatJsonFiles(report_path, reportName, file_number):
file_number = file_number + 1
print("\n Concatinating Reports....")
for l in range(2, file_number):
result_file = report_path[:-4]
result_file = result_file + "_1.txt"
print ("\n" + result_file + "\n")
with open(result_file, 'r') as json_result_file:
json_final_object = json.load(json_result_file)
final_list = json_final_object[reportName]
print(final_list)
read_file = report_path[:-4]
read_file = read_file + "_" + str(l) + ".txt"
with open(read_file, 'r') as temp_json_file:
temp_json_object = json.load(temp_json_file)
list_to_read = temp_json_object[reportName]
json_final_object[reportName].append(list_to_read)
# final_list.append(list_to_read)
with open(result_file, 'w') as json_result:
json.dump(json_final_object, json_result, indent=4)
print("\n Report " + reportName + " ready! > " + report_path + "\n")
# **********************************************
report_path = "/Users/kris/xero.txt"
reportName = "Journals"
total_files = 2
ConcatJsonFiles(report_path, reportName, total_files)
I don't what is in your Input files but I think You can use the extend method instead of the append method to solve your problem.
json_final_object[reportName].extend(list_to_read)
Here is the input list (in file_id.txt):
file-F0Y6GbQ09k704jfGBQX0pgF8
file-FfYqQv00ypGfqQKkF96zX3yV
file-FfYqPf80ypGj712qFBggV2BV
file-FfQpFYQ0ypGqfjkJ8z90Ygzv
file-FfQpFYQ0ypGpQ4K7GGj40VVZ
file-FfQpFYQ0ypGxV3xG7BZQxz3y
file-FfQpFYQ0ypGZ3ZVk7745ZGFf
file-Ff0Qk100ypGYV26V52JZkJ0q
file-FfK1pZ80ypGjgyF73b3fFjgG
Here is the desired output (output.json) :
{
"stage-xxx.input_files": [
{"$dnanexus_link": "file-F0Y6GbQ09k704jfGBQX0pgF8"},
{"$dnanexus_link": "file-FfYqQv00ypGfqQKkF96zX3yV"},
{"$dnanexus_link": "file-FfYqPf80ypGj712qFBggV2BV"},
{"$dnanexus_link": "file-FfQpFYQ0ypGqfjkJ8z90Ygzv"},
{"$dnanexus_link": "file-FfQpFYQ0ypGpQ4K7GGj40VVZ"},
{"$dnanexus_link": "file-FfQpFYQ0ypGxV3xG7BZQxz3y"},
{"$dnanexus_link": "file-FfQpFYQ0ypGZ3ZVk7745ZGFf"},
{"$dnanexus_link": "file-Ff0Qk100ypGYV26V52JZkJ0q"},
{"$dnanexus_link": "file-FfK1pZ80ypGjgyF73b3fFjgG"}
]
}
Here is my current code:
#!/usr/bin/python3 env
fname = input("Enter file name of the list: ")
if len(fname) < 1 : fname = "file_id.txt"
stage_name = input("Enter stage name for the input: ")
if len(stage_name) < 1 : stage_name = "stage-xxx"
input_var = input("Enter input variable name: ")
if len(input_var) < 1 : input_var = "input_files"
fh = open(fname)
out_file = open('output.json', 'w')
out_file.write('{\n "' + f'{stage_name}' + "." + f'{input_var}' + '": [' + "\n")
for line in fh:
fileid = line.rstrip()
out_file.write(" {" + "\"$dnanexus_link\": " + f'"{fileid}"' + "},\n")
out_file.write(' ]\n}\n')
out_file.close()
print("output.json created!")
I am fairly new to python and not sure how to remove the comma at the end of last file in the output json. And I was wondering if there is a way to use the json module to dump the file list into json format without the static text coding..
This code reads your file making the list of dicts as it goes.
I then wrap this list in the final dict and use json.dumps() to get a string:
import json
with open('file_id.txt') as f:
txt = [{'$dnanexus_link': line.strip()} for line in f]
#print(txt)
d = {'stage-xxx.input_files': txt}
print(json.dumps(d))
Output as your output.json but on one line.
I am trying to convert multiple .txt file to "table-like" data (with columns and rows). Each .txt file should be considered as a new column.
Consider below content of the .txt file:
File1.txt
Hi there
How are you doing?
What is your name?
File2.txt
Hi
Great!
Oliver, what's yours?
I have created a simple method, that accepts the file and and integer (the file number from another method):
def txtFileToJson(text_file, column):
data = defaultdict(list)
i = int(1)
with open(text_file) as f:
data[column].append(column)
for line in f:
i = i + 1
for line in re.split(r'[\n\r]+', line):
data[column] = line
with open("output.txt", 'a+') as f:
f.write(json.dumps(data))
So above method will run two times (one time for each file, and append the data).
This is the output.txt file after I have run my script:
{"1": "What is your name?"}{"2": "Oliver, what's yours?"}
As you can see, I can only get it to create a new for each file I have, and then add the entire line.
[{
"1": [{
"1": "Hi there",
"2": "How are you doing?",
"3": "\n"
"4": "What is your name?"
},
"2": [{
"1": "Hi"
"2": "Great!",
"3": "\n",
"4": "Oliver, what's yours?"
},
}]
Update:
OK, so I played around a bit and got a bit closer:
myDict = {str(column): []}
i = int(1)
with open(text_file) as f:
for line in f:
# data[column].append(column)
match = re.split(r'[\n\r]+', line)
if match:
myDict[str(column)].append({str(i): line})
i = i + 1
with open(out_file, 'a+') as f:
f.write(json.dumps(myDict[str(column)]))
That gives me below output:
[{"1": "Hi there\n"}, {"2": "How are you doing?\n"}, {"3": "\n"}, {"4": "What is your name?"}]
[{"1": "Hi\n"}, {"2": "Great!\n"}, {"3": "\n"}, {"4": "Oliver, what's yours?"}]
But as you can see, now I have multiple JSON root elements.
Solution
Thanks to jonyfries, I did this:
data = defaultdict(list)
for path in images.values():
column = column + 1
data[str(column)] = txtFileToJson(path, column)
saveJsonFile(path, data)
And then added a new method to save the final combined list:
def saveJsonFile(text_file, data):
basename = os.path.splitext(os.path.basename(text_file))
dir_name = os.path.dirname(text_file) + "/"
text_file = dir_name + basename[0] + "1.txt"
out_file = dir_name + 'table_data.txt'
with open(out_file, 'a+') as f:
f.write(json.dumps(data))
You're creating a new dictionary within the function itself. So each time you pass a text file in it will create a new dictionary.
The easiest solution seems to be returning the dictionary created and add it to an existing dictionary.
def txtFileToJson(text_file, column):
myDict = {str(column): []}
i = int(1)
with open(text_file) as f:
for line in f:
# data[column].append(column)
match = re.split(r'[\n\r]+', line)
if match:
myDict[str(column)].append({str(i): line})
i = i + 1
with open(out_file, 'a+') as f:
f.write(json.dumps(myDict[str(column)]))
return myDict
data = defaultdict(list)
data["1"] = txtFileToJson(text_file, column)
data["2"] = txtFileToJson(other_text_file, other_column)
def read(text_file):
data, i = {}, 0
with open(text_file) as f:
for line in f:
i = i + 1
data['row_%d'%i] = line.rstrip('\n')
return data
res = {}
for i, fname in enumerate([r'File1.txt', r'File2.txt']):
res[i] = read(fname)
with open(out_file, 'w') as f:
json.dump(res, f)
First, if I understand you are trying to get as output a dictionary of dictionaries, then let me observe that what I understand to be your desired output seems to be enclosing the whole thing within a list, Furthermore, you have unbalanced open and closed list brackets within the dictionaries, which I will ignore, as I will the enclosing list.
I think you need something like:
#!python3
import json
import re
def processTxtFile(text_file, n, data):
d = {}
with open(text_file) as f:
i = 0
for line in f:
for line in re.split(r'[\n\r]+', line):
i = i + 1
d[str(i)] = line
data[str(n)] = d
data = dict()
processTxtFile('File1.txt', 1, data)
processTxtFile('File2.txt', 2, data)
with open("output.txt", 'wt') as f:
f.write(json.dumps(data))
If you really need the nested dictionaries to be enclosed within a list, then replace
data[str(n)] = d
with:
data[str(n)] = [d]