Заменить проиндексированные строки в списке и записать в текстовый файл - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь заменить некоторые слова (по существу, 2-е слово в каждой строке) в текстовом файле, а затем записать их обратно в новый файл или перезаписать существующий файл.

Iмне показалось, что я делаю успехи, но когда я пошел писать в новый файл, я получил сообщение об ошибке, заявив, что не могу записать список в текстовый файл. Я не могу просто заменить слово другим словом, потому что у меня есть предложение else, которое охватывает любое слово, которое не соответствует другому, которое нужно заменить.

Вот пример текста, который я пытаюсь изменить, этот текст содержится в файле .txt:

id int,
organization_id int,
billing_month date,
fee_type varchar(100),
rate float,
price float,
uom varchar(25),
amount float,
currency_code_id float,
process_ts timestamptz NOT NULL DEFAULT (now())::timestamptz(6)

Я хочу изменить:

'int' --> 'BIGINT'
'numeric' --> 'DOUBLE'
'float' --> 'DOUBLE'
ELSE other data type --> 'STRING' .  

В исходных данных обратите внимание, что у некоторых есть другие символы, такие как "varchar (100)" - я хотел бы заменить их на "STRING" и исключить часть (100).

А затем либо перезаписать, либо создать новый текстовый файл. Таким образом, приведенный выше пример вывода при правильной замене будет выглядеть так:

id BIGINT,
organization_id BIGINT,
billing_month STRING,
fee_type STRING,
rate DOUBLE,
price DOUBLE,
uom STRING,
amount DOUBLE,
currency_code_id DOUBLE,
process_ts STRING

У меня проблемы с пониманием, следует ли мне создавать списки, а затем изменять их, а затем записывать эти списки в текстовый файл или словариили какой-то другой метод, о котором я не думаю. Я очень начинающий, поэтому извиняюсь, если это не очень ясно.

Ответы [ 3 ]

1 голос
/ 22 октября 2019

Вы можете перебирать каждую строку и использовать словарь для замены значений во второй позиции каждой строки. Это работает для строк любой длины, если заменяемый текст является вторым словом.

#vals to replace
replace_vals = {'int':'BIGINT', 'numeric':'DOUBLE', 'float':'DOUBLE'}

#file we write to
with open('out.txt', 'w') as outfile:
  #file we read from
  with open ("in.txt", 'r') as infile:
    #check each line
    for line in infile:
      #split line into words
      words = line.split()
      #get the first word and then replace the second word, defaulting to STRING
      w = words[0] + " " + replace_vals.get(words[1], 'STRING')
      #add a final newline
      w += "\n"
      #print to file
      outfile.write(w)

Демо

1 голос
/ 22 октября 2019

Содержимое txt.txt:

id int,
organization_id int,
billing_month date,
fee_type varchar(100),
rate float,
price float,
uom varchar(25),
amount float,
currency_code_id float,
process_ts timestamptz NOT NULL DEFAULT (now())::timestamptz(6)

Код:

with open('txt.txt', 'r') as f:
    text = f.read().splitlines()

mapping = {'int':'BIGINT',
           'numeric':'DOUBLE',
           'float':'DOUBLE'}

replaced_text = []
for line in text:
    # temporarily remove comma
    line = line.rstrip(',')
    split_line = line.split()
    other_text, dtype = split_line[0], split_line[1:]
    new_dtype = mapping.get(' '.join(dtype), 'STRING')
    new_line = '{} {},\n'.format(other_text, new_dtype)
    replaced_text.append(new_line)


with open('txt_replaced.txt', 'w') as f:
    f.writelines(replaced_text)

Содержимое txt_replaced.txt:

id BIGINT,
organization_id BIGINT,
billing_month STRING,
fee_type STRING,
rate DOUBLE,
price DOUBLE,
uom STRING,
amount DOUBLE,
currency_code_id DOUBLE,
process_ts STRING,
0 голосов
/ 22 октября 2019

Может быть, что-то вроде этого может помочь вам:

import os, sys
from re import match as regexSearch

path = os.path.dirname(__file__)
myFile = open(os.path.join(path, "filename.txt"), "r")

regExpr = r"[\w_]+ ([\w\(\)\d:]+)(,|\s)"


with open(os.path.join(path, "newFile.txt"), "w") as f:
    for line in myFile.readlines():
        match = regexSearch(regExpr, line)
        if match:
            result = match.group(1)
            if "int" in result:
                f.write(line.replace(result, "BIGINT"))
            elif result in ["numeric", "float"]:
                f.write(line.replace(result, "DOUBLE"))
            else:
                f.write(line.replace(result, "STRING"))
        else:
            print("couldn't find something in line:\n", line)
    f.close()

...