Экспорт столбцов в несколько текстовых файлов

Автор Zoldic, 13 февраля 2021, 08:51

0 Пользователи и 1 гость просматривают эту тему.

Zoldic

Доброго времени суток! столкнулся с такой задачей, сестра попросила разделить строки из текстового файла (txt) записи расположены строками по два значения и разделены знаком ; образуют как бы по два столбца, все это вручную делается легко, но когда файлов тысячи, то задача не так тривиальна. В начале нужно открыть через LibreOffice calc текстовый файл, потом разделить текст, сделал шаблон, кидаю файл в рабочую область и открывается импорт текста, заранее настроенный шаблон на разделение точка с запятой, жму ок и имею два столбца с текстом, первая задача выполнена, вторая задача нужно столбцы сохранить по отдельности в разные текстовые файлы с расширением (txt) по разным папкам и эти две задачи нужно объединить и автоматизировать. Решил записать макрос на LibreOffice, все настроил, но не тут то было, действия записываются только с одним столбцом, забросил эту идею. Нашел множество макросов с нужными мне функциями, но они для exel, синтаксис похож, но многие команды libreoffice не поддерживает, нашел похожий макрос написанный для libreoffice:
Sub ExportAllToCsv
document = ThisComponent

' Use the global string tools library to generate a base filename for each CSV
' based on the current prefixless filename
GlobalScope.BasicLibraries.loadLibrary("Tools")
BaseFilename = Tools.Strings.GetFileNameWithoutExtension(document.getURL(), "/")

' Work out number of sheets for looping over them later.
Sheets = document.Sheets
NumSheets = Sheets.Count - 1

' Set up a propval object to store the filter properties
Dim Propval(1) as New com.sun.star.beans.PropertyValue
Propval(0).Name = "FilterName"
Propval(0).Value = "Text - txt - csv (StarCalc)"
Propval(1).Name = "FilterOptions"
Propval(1).Value ="59,34,0,1,1"   'ASCII  59 = ;  34 = "

For I = 0 to NumSheets
' For each sheet, assemble a filename and save using the filter
SheetName = Sheets(I).Name
document.getCurrentController.setActiveSheet(Sheets(I))
Filename = "/tmp/" + BaseFilename + "." + SheetName + ".csv"
FileURL = convertToURL(Filename)
document.StoreAsURL(FileURL, Propval())
Next I

' Libreoffice thinks our filename is now the last-exported-CSV filename, so close.
Msgbox "Files saved as /tmp/" + BaseFilename + ".*.csv. You'll need to close the spreadsheet now."
End Sub

но проблема в том что он не разделяет столбцы на отдельные файлы и не сохраняет в формат(txt) а в (csv), вопрос вот в чем, пытаться переделать этот макрос под свои задачи или же проще написать с нуля? какие будут мысли?

bigor

Доброго
Мне кажется это проще решается без офисов. В любом текстовом редакторе поддерживающим регулярные выражения вначале меняем все по ; на пусто, сохраняем. Затем все с ; до конца и сохраняем. При желании можно скрипт на cmd или bash написать.
Если хочется макросом LO то как вариант переносим второй столбец на второй лист и сохраняем по очереди 2 листа. scv это практически тот же txt так что просто меняете расширение в макросе
Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

economist

Цитата: Zoldic от 13 февраля 2021, 08:51они для exel, синтаксис похож, но многие команды libreoffice не поддерживает,

Вверху модуля напишите:

Option VBASupport 1

и 60-80% VBA кода заработают сразу, а остальные можно поправить.

Но в данном случае Calc - лишнее звено (когда файлов тысячи). Есть десятки утилит командной строки по разделению файлов (это будут в основном скрипты на Perl/Python/BAT/CMD). А еще проще - при чтении игнорировать то что после ; или после.



Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

economist

#3
Вот скрипт на языке Python, написан за 3 минуты, зацените лаконичность и читаемость.


import sys, glob, pandas as pd
txts =  glob.glob('D:\\TEST\\*.txt')
out_dir = 'D:\\OUT\\'
for txt in txts:
   df = pd.read_csv(txt, encoding='cp1251', sep=';')
   df.iloc[:,0].to_csv(out_dir + '1' + txt.split('\\')[-1], index=False)
   df.iloc[:,1].to_csv(out_dir + '2' + txt.split('\\')[-1], index=False)


Проще скачать Python c python.org (всё по умолчанию), установить библиотеку pandas командой pip install pandas и запустить скрипт (вставить код выше в файл с именем *.py), указав свои пути. Чтение рекурсивное, структура каталогов в OUT будет повторена.

Кстати, Python есть и внутри OpenOffice|LibreOffice, но стараниями разработчиков из него удалена утилита pip. О том как её поставить - кишит интернет.  

UPD: Любая кастомизация скрипта легко дается, т.к. язык очень высокоуровневый. Например, если нужно расширение именно *.csv. то это делается путем отрезания хвоста и допиской суффикса (рассказывать дольше, чем сразу написать):

+ txt.split('\\')[-1][:-4]+'.csv'
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Zoldic

Цитата: Bigor от 13 февраля 2021, 09:46Мне кажется это проще решается без офисов
гениальное предложение, в начале у меня проскочила мысль сделать это в notepad++ но про регулярные выражения я совсем забыл, проблему решил за несколько минут открыл все нужные файлы, потом поиск > замена... > замена, в поле найти вставляем выражение ;.* и заменить во всех открытых документах, вторую часть точно так же но другое выражение .*; удаляем левое значение до знака ; правое остается, дел было на 10 минут, но как говорится "мы простых путей не ищем" ;D видимо просто мне так хотелось покопаться с LibreOffice. Ребята всем спасибо что откликнулись, многие написали интересные фичи, тоже возьму на заметку ;)