- -
txt в csv
(
http://forum.oszone.net/showthread.php?t=338909)
txt в csv
Здравствуйте!
Есть текстовый файл 190124.txt (имя постоянно будет меняться) содержания 5:4:7:8:4: (будет меняться)
Нужно на выходе получить содержимое файла 5;4;7;8;4; файл должен быть csv (190124.csv)
Как это проще всего реализовать?
|
т.е. нужно в файле заменить все ":" на ";" и поменять расширение?
|
Для такого я обычно использую блокнот. А если файлов много и их лень открывать - Notepad++. Ну а переименование файлов это и вовсе банальная штука (мне, конечно, больше нравится TC, но тут уж, конечно на вкус и цвет).
|
Это и делается вручную в блокноте. А надо через планировщик автоматически.
|
porokh, на WSH:
Скрытый текст
Код:
Option Explicit
Dim strSourceFile
Dim objFSO
Dim strContent
If WScript.Arguments.Count = 1 Then
strSourceFile = WScript.Arguments.Item(0)
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strSourceFile) Then
With objFSO.OpenTextFile(strSourceFile)
strContent = .ReadAll()
.Close
End With
With objFSO.CreateTextFile(objFSO.GetBaseName(strSourceFile) & ".csv", True)
.Write Replace(strContent, ":", ";")
.Close
End With
Else
WScript.Echo "Can't find source file [" & strSourceFile & "]."
WScript.Quit 2
End If
Set objFSO = Nothing
Else
WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source file>"
WScript.Quit 1
End If
WScript.Quit 0
Путь к исходному файлу указывается аргументом скрипта (также можно просто перетащить исходный файл на скрипт/ярлык на скрипт в Проводнике). Существующий csv-файл, одноимённый исходному, будет молча перезаписан.
P.S. Если размер Вашего исходного файла составляет более четверти размера физической оперативной памяти — пишите, сменим алгоритм на более щадяший к расходам оперативной памяти.
|
По простому, не усложняя
Код:
setlocal enabledelayedexpansion
set in=in.txt
set out=out.csv
for /f "delims=" %%n in (%in%) do (
set line=%%n
set line=!line::=;!
@echo !line!>>%out%
)
endlocal
|
sov44, вывод лучше вынести за пределы цикла разбора — намного быстрее будет. И промежуточное присваивание можно убрать. Наподобие:
Код:
…
>"%out%"" (
for /f "delims=" %%n in (%in%) do (
set line=%%n
@echo !line::=;!
)
)
…
|
Всем спасибо за помощь!!!
|
porokh,
Вот еще вариант
Код:
@Echo Off
Set "File=Z:\Soft_In\*.txt"
Set "BoxOut=Z:\Soft_Out"
Set "BoxArc=Z:\Soft_In\Arc"
Set "ExtOut=csv"
Set "Sym1=:"
Set "Sym2=;"
If Not Exist "%BoxArc%" Md "%BoxArc%"
FOR %%f IN ("%File%") DO (
>"%BoxOut%\%%~nf.%ExtOut%" (FOR /F "usebackq delims=" %%s IN (`2^>nul more "%%f"`) DO (
Set "SS=%%s"
Call Echo %%SS:%Sym1%=%Sym2%%%
))
>nul Move /Y "%%f" "%BoxArc%\"
)
Во входной папке обрабатываются файлы по маске, заменяются указанные символы, файлы сохраняются в указанной выходной папке по заданному расширению, исходные файлы перемещаются в архив, чтобы больше их не обрабатывать при последующем запуске батника, так как Вам надо
Цитата:
Цитата porokh
через планировщик автоматически. »
|
ИМХО, Вы изложили только часть задачи. Что дальше происходит с CSV-файлами?
|
я правильно понимаю что в файле источнике единственная строка?
Код:
@echo off
set "maska=1*"
for %%a in ("%maska%.txt") do <"%%~a">"%%~na.csv" (set /p s=& call echo %%s::=;%%)
pause
|
Кол-во строк меняется.
Файл технический, данные потом оператор расшифровывает.
|
?
csv это зачастую однострочник, нигде в кодах выше не собирали строки в одну и вы не жаловались, поэтому и предположил что строка одна.
|
Цитата:
Цитата alpap
csv это зачастую однострочник »
|
это вырожденный случай
возможно, характерный для какой-то конкретной специфичной области
Цитата:
Цитата porokh
Как это проще всего реализовать? »
|
если в реальности во входном файле не цифры, а более произвольное содержание - отказаться от использования cmd/bat:
либо найти готовую утилиту, либо перейти на powershell
штатными средствами это решается и на vbs, но переходить на него сейчас - полный бесперспективняк, а в jscript не реализована простая замена текста
|
Цитата:
Цитата alpap
нигде в кодах выше не собирали строки в одну »
|
Но и не разбирали ;).
|
не понял. Ну да, там строки просто не трогали (за исключением внутренних изменений), а выше я написал что представлял себе csv как однострочник и мой код выше правильно будет работать с файлом из одной строки, вернее заберет из файла только первую строку, изменит ее и поместит в новый, остальные строки не тронет, что будет уже неправильно с учетом дополнения Busla
насколько я понял ТС в теме и я не стал зацикливаться на этом.
|
alpap, решение элегантнейшее, хоть и не подходит клиенту
|
Цитата:
Цитата Busla
в jscript не реализована простая замена текста »
|
что значит простая замена?
В смысле это:
Код:
stringObj.replace(rgExp, replaceText)
?
|
Цитата:
Цитата Iska
porokh, на WSH:
Код:
…
With objFSO.OpenTextFile(strSourceFile)
strContent = .ReadAll()
.Close
End With
With objFSO.CreateTextFile(objFSO.GetBaseName(strSourceFile) & ".csv", True)
.Write Replace(strContent, ":", ";")
.Close
End With
…
»
|
— левые кадеты, правые кадеты, какая к чёрту разница, если у тебя есть ружьё одна строка или несколько строк — неважно, читаем-пишем всё зараз.
Цитата:
Цитата Busla
штатными средствами это решается и на vbs, но переходить на него сейчас - полный бесперспективняк »
|
«А я сынок, всё одну, всё одну»™. Вы пишете, как будто это что-то плохое.
|
YuS_2, по-моему, очевидно, что regexp - это не простая замена подстрок
|
Цитата:
Цитата Busla
простая замена подстрок »
|
А что будет простой заменой? И есть ли необходимость в ней?
К тому же, шаблон регулярки, вполне себе, может быть полным, простым текстом - чего не хватает в этом методе?
|
Цитата:
Цитата YuS_2
шаблон регулярки, вполне себе, может быть полным, простым текстом - чего не хватает в этом методе? »
|
а может быть и не простым текстом ;-)
когда текст - переменный, а шаблон - захардкоженная константа - всё ok
а когда найти нужно произвольную подстроку - пользователь ввёл, или в одном файле нужно найти строки из другого - случается жопа. Т.к. нужно изобретать способ экранирования синтаксиса регулярных выражений.
|
YuS_2, Шаблон регулярки для замены подстроки, в общем случае, в JS, имхо сложноватый. В VBS реплэйс организован проще.
Вот вариант VBS, ориентированный для применения в планировщике.
Во входной папке обрабатываются файлы по маске, заменяются указанные символы, файлы сохраняются в указанной выходной папке по заданному расширению, исходные файлы перемещаются в архив, чтобы больше их не обрабатывать при последующем запуске батника
Код:
BoxIn = "Z:\Soft_In"
FileIn = "^.*\.txt$" ' *.txt
BoxOut = "Z:\Soft_Out"
BoxArc = "Z:\Soft_In\Arc"
ExtOut = "csv"
Str1 = ":"
Str2 = ";"
Set RegMaska = CreateObject("VBScript.RegExp")
RegMaska.Pattern = FileIn
RegMaska.IgnoreCase = True
With CreateObject("Scripting.FileSystemObject")
On Error Resume Next
Set Folds = .GetFolder(BoxIn)
If Err.Number <> 0 Then
MsgBox "Ошибка при открытии папки" + vbCrLf + BoxIn + vbCrLf + vbCrLf + Err.Description
WScript.Quit 2
End If
On Error GoTo 0
Set Files = Folds.Files
For Each jf In Files
If RegMaska.Test(jf) Then
On Error Resume Next
Set fIn = .OpenTextFile(jf, 1, False)
If Err.Number <> 0 Then
MsgBox "Ошибка при открытии файла" + vbCrLf + .GetAbsolutePathName(jf) + vbCrLf + vbCrLf + Err.Description
WScript.Quit 2
End If
On Error GoTo 0
Alls = fIn.ReadAll
fIn.Close
NewName = BoxOut + "\" + .GetBaseName(jf) + "." + ExtOut
ArcName = BoxArc + "\" + .GetFileName(jf)
On Error Resume Next
Set fIn = .CreateTextFile(NewName, True)
If Err.Number <> 0 Then
MsgBox "Ошибка при создании файла" + vbCrLf + BoxOut + "\" + .GetBaseName(jf) + "." + ExtOut + vbCrLf + vbCrLf + Err.Description
WScript.Quit 2
End If
On Error GoTo 0
fIn.Write Replace(Alls, Str1, Str2)
fIn.Close
If .FileExists(ArcName) Then fIn=.DeleteFile(ArcName,True)
fIn = .MoveFile(.GetAbsolutePathName(jf), ArcName)
End If
Next
End With
' MsgBox "Скрипт завершен"
|
Цитата:
Цитата Busla
а может быть и не простым текстом ;-) »
|
не могу не согласиться ;-)
Цитата:
Цитата Busla
Т.к. нужно изобретать способ экранирования синтаксиса регулярных выражений. »
|
А, вот про что речь.... т.е. если шаблон вводится ручками или берется из неизвестного заранее текста? Это да, есть такой момент... но тут уж вряд ли что-либо изменится, ибо язык останется статичным навечно, скорее всего.
Цитата:
Цитата megaloman
Шаблон регулярки для замены подстроки, в общем случае, в JS, имхо сложноватый. В VBS реплэйс организован проще. »
|
В общем случае, всё может считаться сложным... а вообще, сложность - понятие относительное, имхо. Тут бы пример какой-нибудь, был бы гораздо нагляднее...
ЗЫ да и я ведь не говорю ничего против того, что устаревают эти инструменты (wsh), потому и powershell пришел на замену всей этой связки. Но, увы, во всех абсолютно случаях полная замена пока невозможна и по большей части, именно из-за политики микрософт. Ведь даже в самом powershell есть много нюансов, привязанных даже не к версии PoSh, а к версии ОС, причем даже в пределах одной линейки номера этой ОС. Это вызывает удивление/раздражение и прочие отрицательные чувства, что естественно... А вот бороться с этим можно только кардинальным образом, то бишь сменой windows на что-то более другое. :)
|
DJ Mogarych |
29-01-2019 11:29 2855136 |
Powershell:
Код:
import-csv .\190124.txt -Delimiter ":" | export-csv .\190124.csv -Delimiter ";"
Цитата:
Цитата YuS_2
в самом powershell есть много нюансов, привязанных даже не к версии PoSh, а к версии ОС, причем даже в пределах одной линейки номера этой ОС »
|
Например?
|
Например, выполните команду get-disk в PoSh v5.1 под Win7 и под Win 10, сравните результат.
Да и вообще, сравнить можно результаты команды get-command...
|
Фокус не удастся :):
Цитата:
Код:
import-csv : The member "4" is already present.
At line:1 char:1
+ import-csv 'C:\Мои проекты\0240\0002.csv' -Delimiter ":" | export-csv ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Import-Csv], ExtendedTypeSystemException
+ FullyQualifiedErrorId : AlreadyPresentPSMemberInfoInternalCollectionAdd,Microsoft.PowerShell.Commands.ImportCsvCommand
|
Один и тот же код в одной и той же версии PowerShell 2.0 с одними и теми же входными данными возвращал разные результаты под разными ОС (Windows XP и Windows 7).
|
DJ Mogarych |
31-01-2019 11:08 2855527 |
Я взял нормальный CSV в текстовом формате. Если формат кривой, то ничего и не выйдет, это понятно.
Цитата:
Цитата Iska
разные результаты под разными ОС (Windows XP и Windows 7). »
|
То, что на старые операционки не ставится новый Powershell, понятно. Мне непонятен пассаж про
Цитата:
Цитата YuS_2
причем даже в пределах одной линейки номера этой ОС »
|
|
DJ Mogarych, формат не кривой. Iska туда засунул csv без заголовков, буквально тот, что в примере топикстартера.
|
А что тут непонятного? Windows 10 во всех её вариациях... если, например, скрипт работать должен с магазином, а магазин этот физически отсутствует, что получим в итоге? Ну и т.п.
Цитата:
Цитата DJ Mogarych
на старые операционки не ставится новый Powershell »
|
на windows 7, вполне себе, устанавливается v5.1 ...
к тому же, речь ведь была о:
Цитата:
Цитата Iska
Один и тот же код в одной и той же версии PowerShell 2.0 с одними и теми же входными данными возвращал разные результаты под разными ОС »
|
Цитата:
Цитата Busla
Iska туда засунул csv без заголовков »
|
А в csv обязан быть заголовок?
RFC - 4180
Цитата:
Допускается строка заголовка в первой строке в том же формате, что и обычная строка
записи. Этот заголовок будет содержать имена, соответствующие полям в файле и должен
содержать то же количество полей, что и записи в остальной части файла (наличие или
отсутствие строки заголовка должно быть указано с помощью дополнительного параметра
"header" ("заголовок")
|
если требуется powershell, просто надо определить свои заголовки:
Код:
import-csv 1.txt -enc utf8 -head p1,p2,p3,p4,p5 -del ':'|export-csv 1.csv -enc utf8 -del ',' -not
|
Цитата:
Цитата DJ Mogarych
Я взял нормальный CSV в текстовом формате. Если формат кривой, то ничего и не выйдет, это понятно. »
|
А кто сказал, что это CSV?!
Цитата:
Цитата DJ Mogarych
То, что на старые операционки не ставится новый Powershell, понятно. »
|
Повторяю — речь шла про одну и ту же версию PowerShell. Конкретно, вторую.
Цитата:
Цитата YuS_2
если требуется powershell, просто надо определить свои заголовки: »
|
YuS_2, вот-вот. Я лично надеялся увидеть у командлета просто какой-нибудь параметр -NoHeading. Но увы.
|
Время: 11:29.
© OSzone.net 2001-