Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   txt в csv (http://forum.oszone.net/showthread.php?t=338909)

porokh 25-01-2019 15:39 2854540

txt в csv
 
Здравствуйте!
Есть текстовый файл 190124.txt (имя постоянно будет меняться) содержания 5:4:7:8:4: (будет меняться)
Нужно на выходе получить содержимое файла 5;4;7;8;4; файл должен быть csv (190124.csv)
Как это проще всего реализовать?

Elven 25-01-2019 17:09 2854569

т.е. нужно в файле заменить все ":" на ";" и поменять расширение?

porokh 25-01-2019 17:24 2854573

именно так

Elven 25-01-2019 18:26 2854589

Для такого я обычно использую блокнот. А если файлов много и их лень открывать - Notepad++. Ну а переименование файлов это и вовсе банальная штука (мне, конечно, больше нравится TC, но тут уж, конечно на вкус и цвет).

porokh 25-01-2019 19:29 2854603

Это и делается вручную в блокноте. А надо через планировщик автоматически.

Iska 25-01-2019 19:44 2854608

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. Если размер Вашего исходного файла составляет более четверти размера физической оперативной памяти — пишите, сменим алгоритм на более щадяший к расходам оперативной памяти.

sov44 25-01-2019 20:03 2854614

По простому, не усложняя
Код:

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


Iska 25-01-2019 20:21 2854618

sov44, вывод лучше вынести за пределы цикла разбора — намного быстрее будет. И промежуточное присваивание можно убрать. Наподобие:
Код:


>"%out%"" (
        for /f "delims=" %%n in (%in%) do (
                set line=%%n
                @echo !line::=;!
        )
)


porokh 25-01-2019 20:54 2854622

Всем спасибо за помощь!!!

megaloman 25-01-2019 21:42 2854632

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-файлами?

alpap 25-01-2019 22:15 2854636

Цитата:

Цитата porokh
содержания 5:4:7:8:4: »

я правильно понимаю что в файле источнике единственная строка?
Код:

@echo off
set "maska=1*"

for %%a in ("%maska%.txt") do <"%%~a">"%%~na.csv" (set /p s=& call echo %%s::=;%%)
pause


porokh 26-01-2019 00:55 2854660

Кол-во строк меняется.
Файл технический, данные потом оператор расшифровывает.

alpap 26-01-2019 03:38 2854670

Цитата:

Цитата porokh
Кол-во строк меняется »

?
csv это зачастую однострочник, нигде в кодах выше не собирали строки в одну и вы не жаловались, поэтому и предположил что строка одна.

Busla 26-01-2019 12:41 2854706

Цитата:

Цитата alpap
csv это зачастую однострочник »

это вырожденный случай
возможно, характерный для какой-то конкретной специфичной области


Цитата:

Цитата porokh
Как это проще всего реализовать? »

если в реальности во входном файле не цифры, а более произвольное содержание - отказаться от использования cmd/bat:
либо найти готовую утилиту, либо перейти на powershell
штатными средствами это решается и на vbs, но переходить на него сейчас - полный бесперспективняк, а в jscript не реализована простая замена текста

Iska 26-01-2019 15:19 2854730

Цитата:

Цитата alpap
нигде в кодах выше не собирали строки в одну »

Но и не разбирали ;).

alpap 26-01-2019 20:42 2854775

Цитата:

Цитата Iska
Но и не разбирали »

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

Цитата Busla
это вырожденный случай »

насколько я понял ТС в теме и я не стал зацикливаться на этом.

megaloman 26-01-2019 21:25 2854784

alpap, решение элегантнейшее, хоть и не подходит клиенту

YuS_2 26-01-2019 21:57 2854794

Цитата:

Цитата Busla
в jscript не реализована простая замена текста »

что значит простая замена?
В смысле это:
Код:

stringObj.replace(rgExp, replaceText)
?

Iska 26-01-2019 23:01 2854802

Цитата:

Цитата alpap
не понял. »

Цитата:

Цитата 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, но переходить на него сейчас - полный бесперспективняк »

«А я сынок, всё одну, всё одну»™. Вы пишете, как будто это что-то плохое.

Busla 27-01-2019 14:28 2854872

YuS_2, по-моему, очевидно, что regexp - это не простая замена подстрок

YuS_2 27-01-2019 15:13 2854883

Цитата:

Цитата Busla
простая замена подстрок »

А что будет простой заменой? И есть ли необходимость в ней?
К тому же, шаблон регулярки, вполне себе, может быть полным, простым текстом - чего не хватает в этом методе?

Busla 27-01-2019 15:53 2854888

Цитата:

Цитата YuS_2
шаблон регулярки, вполне себе, может быть полным, простым текстом - чего не хватает в этом методе? »

а может быть и не простым текстом ;-)
когда текст - переменный, а шаблон - захардкоженная константа - всё ok
а когда найти нужно произвольную подстроку - пользователь ввёл, или в одном файле нужно найти строки из другого - случается жопа. Т.к. нужно изобретать способ экранирования синтаксиса регулярных выражений.

megaloman 27-01-2019 20:17 2854942

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 "Скрипт завершен"


YuS_2 28-01-2019 11:58 2855001

Цитата:

Цитата 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, а к версии ОС, причем даже в пределах одной линейки номера этой ОС »

Например?

YuS_2 29-01-2019 12:54 2855146

Цитата:

Цитата DJ Mogarych
Например? »

Например, выполните команду get-disk в PoSh v5.1 под Win7 и под Win 10, сравните результат.
Да и вообще, сравнить можно результаты команды get-command...

Iska 29-01-2019 14:16 2855163

Цитата:

Цитата DJ Mogarych
Powershell: »

Фокус не удастся :):
Цитата:

Код:

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


Цитата:

Цитата DJ Mogarych
Например? »

Один и тот же код в одной и той же версии PowerShell 2.0 с одними и теми же входными данными возвращал разные результаты под разными ОС (Windows XP и Windows 7).

DJ Mogarych 31-01-2019 11:08 2855527

Цитата:

Цитата Iska
Фокус не удастся »

Я взял нормальный CSV в текстовом формате. Если формат кривой, то ничего и не выйдет, это понятно.
Цитата:

Цитата Iska
разные результаты под разными ОС (Windows XP и Windows 7). »

То, что на старые операционки не ставится новый Powershell, понятно. Мне непонятен пассаж про
Цитата:

Цитата YuS_2
причем даже в пределах одной линейки номера этой ОС »


Busla 31-01-2019 12:46 2855550

DJ Mogarych, формат не кривой. Iska туда засунул csv без заголовков, буквально тот, что в примере топикстартера.

YuS_2 31-01-2019 15:07 2855574

Цитата:

Цитата DJ Mogarych
непонятен пассаж про »

А что тут непонятного? 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

Iska 31-01-2019 19:02 2855613

Цитата:

Цитата DJ Mogarych
Я взял нормальный CSV в текстовом формате. Если формат кривой, то ничего и не выйдет, это понятно. »

А кто сказал, что это CSV?!

Цитата:

Цитата DJ Mogarych
То, что на старые операционки не ставится новый Powershell, понятно. »

Повторяю — речь шла про одну и ту же версию PowerShell. Конкретно, вторую.

Цитата:

Цитата YuS_2
если требуется powershell, просто надо определить свои заголовки: »

YuS_2, вот-вот. Я лично надеялся увидеть у командлета просто какой-нибудь параметр -NoHeading. Но увы.


Время: 05:11.

Время: 05:11.
© OSzone.net 2001-