Сравните два текстовых файла и запишите соответствующие значения в текстовый файл - PullRequest
1 голос
/ 24 апреля 2020

У меня есть два текстовых файла: Speech.txt и Script.txt . Speech.txt содержит список имен файлов аудиофайлов, а Script.txt содержит соответствующую расшифровку. Script.txt содержит стенограммы для всех символов и элементов, однако я хочу, чтобы транскрипция была указана только для c символов только . Я хочу написать скрипт python, который сравнивает имя файла с транскриптом и возвращает текстовый файл, содержащий путь к файлу, имя файла, расширение и транскрипт, разделенные | .

Образец Speech.txt:

0x000f4a03.wav
0x000f4a07.wav
0x000f4a0f.wav

Образец Script.txt:

0x000f4a0f |            | And unites the clans against Nilfgaard?
0x000f4a11 |            | Of course. He's already decreed new longships be built.
0x000f4a03 |            | Thinking long-term, then. Think she'll succeed?
0x000f4a05 |            | She's got a powerful ally. In me.
0x000f4a07 |            | Son's King of Skellige. Congratulations to you.

Ожидаемый результат:

C:/Speech/0x000f4a03.wav|Thinking long-term, then. Think she'll succeed?
C:/Speech/0x000f4a07.wav|Son's King of Skellige. Congratulations to you.
C:/Speech/0x000f4a0f.wav|And unites the clans against Nilfgaard?

Код (в процессе):

f1=open(r'C:/Speech.txt',"r", encoding='utf8')
f2=open(r'C:/script.txt',"r", encoding='utf8')
for line1 in f1:
    for line2 in f2:
        if line1[0:10]==line2[0:10]:
              print('C:/Speech/' + line2[0:10] + '.wav' + '|' + line2[26:-1])              
f1.close()
f2.close()

Вышеприведенный код работает только для первой строки в Speech.txt, а затем останавливается. Я хочу, чтобы он прошел через весь файл, т.е. строка 2, строка 3 ... et c. Я также не понял, как вывести результаты в текстовый файл. Я могу только распечатать результаты на данный момент. Буду признателен за любую помощь!

РЕДАКТИРОВАТЬ Ссылки на Script.txt и Speech.txt .

Ответы [ 4 ]

1 голос
/ 24 апреля 2020

Для каждой строки файла Speech.txt необходимо проверить, существует ли он в файле Script.txt. Учитывая, что содержимое Script.txt помещается в память, вы должны загрузить его, чтобы не читать его каждый раз.

После загрузки содержимого Script.txt вы просто обрабатываете каждую строку Speech.txt, ищете ее в словаре и распечатываете ее при необходимости.

Далее я предоставляю код , Обратите внимание:

  • Я добавил отладочную информацию. Вы можете скрыть это, выполнив python -O script.py
  • Я использую os.path.splittext(var)[0], чтобы удалить расширение из имени файла
  • I strip каждой обработанной строки, чтобы избавиться от пробелов / разрывов строк.

Код:

#!/usr/bin/python

# -*- coding: utf-8 -*-

# For better print formatting
from __future__ import print_function

# Imports
import sys
import os


#
# HELPER METHODS
#
def load_script_file(script_file_path):
    # Parse each line of the script file and load to a dictionary
    d = {}
    with open(script_file_path, "r") as f:
        for transcript_info in f:
            if __debug__:
                print("Loading line: " + str(transcript_info))
            speech_filename, _, transcription = transcript_info.split("|")
            speech_filename = speech_filename.strip()
            transcription = transcription.strip()
            d[speech_filename] = transcription

    if __debug__:
        print("Loaded values: " + str(d))
    return d


#
# MAIN METHODS
#

def main(speech_file_path, script_file_path, output_file):
    # Load the script data into a dictionary
    speech_to_transcript = load_script_file(script_file_path)

    # Check each speech entry
    with open(speech_file_path, "r") as f:
        for speech_audio_file in f:
            speech_audio_file = speech_audio_file.strip()
            if __debug__:
                print()
                print("Checking speech file: " + str(speech_audio_file))

            # Remove extension
            speech_code = os.path.splitext(speech_audio_file)[0]
            if __debug__:
                print(" + Obtained filename: " + speech_code)

            # Find entry in transcript
            if speech_code in speech_to_transcript.keys():
                if __debug__:
                    print(" + Filename registered. Loading transcript")
                transcript = speech_to_transcript[speech_code]
                if __debug__:
                    print(" + Transcript: " + str(transcript))

                # Print information
                output_line = "C:/Speech/" + speech_audio_file + "|" + transcript
                if output_file is None:
                    print(output_line)
                else:
                    with open(output_file, 'a') as fw:
                        fw.write(output_line + "\n")
            else:
                if __debug__:
                    print(" + Filename not registered")


#
# ENTRY POINT
#
if __name__ == '__main__':
    # Parse arguments
    args = sys.argv[1:]
    speech = str(args[0])
    script = str(args[1])
    if len(args) == 3:
        output = str(args[2])
    else:
        output = None

    # Log arguments if required
    if __debug__:
        print("Running with:")
        print(" - SPEECH FILE = " + str(speech))
        print(" - SCRIPT FILE = " + str(script))
        print(" - OUTPUT FILE = " + str(output))
        print()

    # Execute main
    main(speech, script, output)

Отладочный вывод:

$ python speech_transcript.py ./Speech.txt ./Script.txt
Running with:
 - SPEECH FILE = ./Speech.txt
 - SCRIPT FILE = ./Script.txt

Loaded values: {'0x000f4a03': "Thinking long-term, then. Think she'll succeed?", '0x000f4a11': "Of course. He's already decreed new longships be built.", '0x000f4a05': "She's got a powerful ally. In me.", '0x000f4a07': "Son's King of Skellige. Congratulations to you.", '0x000f4a0f': 'And unites the clans against Nilfgaard?'}

Checking speech file: 0x000f4a03.wav
 + Obtained filename: 0x000f4a03
 + Filename registered. Loading transcript
 + Transcript: Thinking long-term, then. Think she'll succeed?
C:/Speech/0x000f4a03.wav|Thinking long-term, then. Think she'll succeed?

Checking speech file: 0x000f4a07.wav
 + Obtained filename: 0x000f4a07
 + Filename registered. Loading transcript
 + Transcript: Son's King of Skellige. Congratulations to you.
C:/Speech/0x000f4a07.wav|Son's King of Skellige. Congratulations to you.

Checking speech file: 0x000f4a0f.wav
 + Obtained filename: 0x000f4a0f
 + Filename registered. Loading transcript
 + Transcript: And unites the clans against Nilfgaard?
C:/Speech/0x000f4a0f.wav|And unites the clans against Nilfgaard?

Выход:

$ python -O speech_transcript.py ./Speech.txt ./Script.txt 
C:/Speech/0x000f4a03.wav|Thinking long-term, then. Think she'll succeed?
C:/Speech/0x000f4a07.wav|Son's King of Skellige. Congratulations to you.
C:/Speech/0x000f4a0f.wav|And unites the clans against Nilfgaard?

Вывод записи в файл:

$ python -O speech_transcript.py ./Speech.txt ./Script.txt ./output.txt
$ more output.txt 
C:/Speech/0x000f4a03.wav|Thinking long-term, then. Think she'll succeed?
C:/Speech/0x000f4a07.wav|Son's King of Skellige. Congratulations to you.
C:/Speech/0x000f4a0f.wav|And unites the clans against Nilfgaard?
1 голос
/ 24 апреля 2020

Я бы прочитал содержимое Script.txt в словарь, а затем использовал бы этот словарь в качестве итерации строк из Speech.txt и печатать только существующие строки. Это избавляет от необходимости повторять файл несколько раз, что может быть довольно медленным, если у вас большие файлы.

Демонстрация:

from pathlib import Path

with open("Speech.txt") as speech_file, open("Script.txt") as script_file:
    script_dict = {}
    for line in script_file:
        key, _, text = map(str.strip, line.split("|"))
        script_dict[key] = text

    for line in map(str.strip, speech_file):
        filename = Path(line).stem
        if filename in script_dict:
            print(f"C:\Speech\{line}|{script_dict[filename]}")

Вывод:

C:\Speech\0x000f4a03.wav|Thinking long-term, then. Think she'll succeed?
C:\Speech\0x000f4a07.wav|Son's King of Skellige. Congratulations to you.
C:\Speech\0x000f4a0f.wav|And unites the clans against Nilfgaard?

Его также намного проще использовать с менеджерами контекста операторов для открытия ваших файлов, поскольку вам не нужно вызывать .close(), чтобы закрыть ваш файл, потому что это обрабатывает это для вас.

Я также использовал pathlib.PurePath.stem, чтобы получить имя файла из ваших файлов .wav. Я считаю, что это проще в использовании, чем функции os.path.basename os.path.spltext. Хотя это личное предпочтение и все будет работать.

Если мы хотим записать вывод в текстовый файл, мы можем открыть другой выходной файл в режиме записи, используя mode="w":

from pathlib import Path

with open("Speech.txt") as speech_file, open("Script.txt") as script_file, open("output.txt", mode="w") as output_file:
    script_dict = {}
    for line in script_file:
        key, _, text = map(str.strip, line.split("|"))
        script_dict[key] = text

    for line in map(str.strip, speech_file):
        filename = Path(line).stem
        if filename in script_dict:
            output_file.write(f"C:\Speech\{line}|{script_dict[filename]}\n")

output.txt

C:\Speech\0x000f4a03.wav|Thinking long-term, then. Think she'll succeed?
C:\Speech\0x000f4a07.wav|Son's King of Skellige. Congratulations to you.
C:\Speech\0x000f4a0f.wav|And unites the clans against Nilfgaard?

Вы можете взглянуть на Чтение и запись файлов из документации для получения дополнительной информации о том, как читать и писать файлы в python.

1 голос
/ 24 апреля 2020

Использование pandas также является другим подходом, поскольку это похоже на вашу типичную проблему объединения.

import pandas as pd

df = pd.read_csv('speech.txt', header=None, names=['name'])
df1 = pd.read_csv('script.txt', sep='|', header=None, names=['name', 'blank', 'description'])

df1['name'] = df1.name.str.strip() + '.wav'

final = pd.merge(df, df1, how='left', left_on='name', right_on='name')
final['name'] = 'C:/Speech/' + final['name']

print(final)

                       name         blank                                       description
0  C:/Speech/0x000f4a03.wav                 Thinking long-term, then. Think she'll succeed?
1  C:/Speech/0x000f4a07.wav                 Son's King of Skellige. Congratulations to you.
2  C:/Speech/0x000f4a0f.wav                         And unites the clans against Nilfgaard?

Тогда нужно просто выбрать нужные столбцы и сохранить их.

final = final[['name', 'description']]
final.to_csv('some_name.csv', index=False, sep='|')
1 голос
/ 24 апреля 2020

Вы можете загрузить строки в списки с помощью метода readlines (), а затем перебрать их. Это позволяет избежать проблемы, связанной с тем, что Кулдип Сингх Сидху правильно уведомил указатель о достижении конца файла.

f1=open(r'C:/Speech.txt',"r", encoding='utf8')
f2=open(r'C:/script.txt',"r", encoding='utf8')
lines1 = f1.readlines()
lines2 = f2.readlines()
f1.close()
f2.close()

with open("output.txt","w") as outfile:
    for line1 in lines1:
        for line2 in lines2:
            if line1[0:10]==line2[0:10]:
                  outfile.write('C:/Speech/' + line2[0:10] + '.wav' + '|' + line2[26:-1],"/n")              
...