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

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

foma24 06-06-2013 15:01 2163315

Добавление числа после точки с условием
 
Добрый день. Помогите решить такую задачу. Есть файл 111.txt который лежит в C:\ в нем много строк текста. Нужно найти строки вида:

Сумм:30
Сумм:10.1
Сумм:50.03

С этих строках, там, где после точки идет одно число в конце нужно дописать 0, т.е. строка Сумм:10.1 должна стать Сумм:10.10, а там где нет точки добавить точку и два нуля, т.е. вместо Сумм:30 должно стать Сумм:30.00, строку с двумя цифрами после точки оставить без изменений.

Файл с изменениями сохранить в 222.txt

P.S. в принципе можно и не в CMD, а в WHS или PowerShell

Georgio 06-06-2013 15:43 2163344

foma24, проверьте:

Код:

@ECHO OFF>222.txt
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=1,2 delims=." %%I IN (111.txt) DO (
  SET VAR1=%%J
  IF DEFINED VAR1 (
    SET VAR2=!VAR1:~1!
    IF DEFINED VAR2 (
    ECHO %%I.%%J>>222.txt
  ) ELSE (
    ECHO %%I.%%J0>>222.txt
)) ELSE (
    ECHO %%I.00>>222.txt
))


foma24 06-06-2013 16:07 2163355

Большое спасибо, только небольшое уточнение, нужно чтобы батник обрабатывал только строки с началом Сумм, т.е. например если в строке будет не Сумм:30 а Итог:30 то такую строку трогать не нужно, она должна в первозданном виде сохраниться в файл 222.txt

Iska 06-06-2013 16:31 2163371

Цитата:

Цитата foma24
Есть файл 111.txt »

Кодировку файла укажите.

У меня какой-то тихий ужас получился:
читать дальше »
Код:

$sPath = "E:\Песочница\0269\111.txt"

$aContent = (
    Get-Content -Path $sPath |`
        ForEach-Object -Process {
            switch -regex ($_) {
                "^Сумм:\d+[^\d.]*$" {
                    $_ -replace "^(Сумм:\d+)([^\d.]*)$", '${1}.00${2}'
                    break
                }
                   
                "^Сумм:\d+\.\d[^\d.]*$" {
                    $_ -replace "^(Сумм:\d+\.\d)([^\d.]*)", '${1}0${2}'
                    break
                }
                default {
                    $_
                }
            }
        }
)
   
Set-Content -Path $sPath -Value $aContent


foma24 06-06-2013 16:41 2163374

Цитата:

Цитата Iska
Кодировку файла укажите. »

OEM866

Iska 06-06-2013 17:40 2163401

Цитата:

Цитата foma24
OEM866 »

Попробуйте так:
читать дальше »
Код:

function StrConvert($sSourceCharset, $sDestCharset) {
    begin {
        Set-Variable -Name adTypeText      -Option Constant -Value 2
        Set-Variable -Name adModeReadWrite -Option Constant -Value 3
       
        $oStream = New-Object -ComObject "ADODB.Stream"
    }
   
        process {
        $oStream.Type = $adTypeText
                $oStream.Mode = $adModeReadWrite
               
                $oStream.Open()
               
                $oStream.Charset = $sSourceCharset
                $oStream.WriteText($_)
               
                $oStream.Position = 0
                $oStream.Charset  = $sDestCharset
                $oStream.ReadText()
               
                $oStream.Close()
        }
}

$sPath = "E:\Песочница\0269\111.txt"

$aContent = (
    Get-Content -Path $sPath  |`
        StrConvert "windows-1251" "cp866" |`
            ForEach-Object -Process {
                $sConvertedString = ($_  )
               
                switch -regex ($sConvertedString) {
                    "^Сумм:\d+[^\d.]*$" {
                        $sConvertedString -replace "^(Сумм:\d+)([^\d.]*)$", '${1}.00${2}'
                        break
                    }
                       
                    "^Сумм:\d+\.\d[^\d.]*$" {
                        $sConvertedString -replace "^(Сумм:\d+\.\d)([^\d.]*)", '${1}0${2}'
                        break
                    }
                    default {
                        $sConvertedString
                    }
                }
            } |`
    StrConvert "cp866" "windows-1251"
)
   
Set-Content -Path $sPath -Value $aContent


Georgio 06-06-2013 17:48 2163405

Код:

@ECHO OFF>222.txt
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=*" %%I IN (111.txt) DO (
  FOR /F "tokens=1,3 delims=:." %%J IN ("%%I") DO (
  IF %%J==Сумм (
    SET VAR1=%%K
    IF DEFINED VAR1 (
    SET VAR2=!VAR1:~1!
    IF DEFINED VAR2 (
      ECHO %%I>>222.txt
  ) ELSE (
      ECHO %%I0>>222.txt
 )) ELSE (
    ECHO %%I.00>>222.txt
)) ELSE (
    ECHO %%I>>222.txt
)))


foma24 06-06-2013 17:49 2163406

Огромное спасибо все прекрасно работает.

Если можно еще одна задачка, файлы внутри такие же, но их много, хранятся в одной папке, нужно в этой папке отобрать все файлы где есть строки вида
Сумм:30
Сумм:10.1
т.е. либо без точки, либо с одной цифрой после точки и скопировать в отдельный каталог

Iska 06-06-2013 19:03 2163443

Кодировка та же? Пробуйте:
читать дальше »
Код:

function StrConvert($sSourceCharset, $sDestCharset) {
    begin {
        Set-Variable -Name adTypeText      -Option Constant -Value 2
        Set-Variable -Name adModeReadWrite -Option Constant -Value 3
       
        $oStream = New-Object -ComObject "ADODB.Stream"
    }
   
        process {
        $oStream.Type = $adTypeText
                $oStream.Mode = $adModeReadWrite
               
                $oStream.Open()
               
                $oStream.Charset = $sSourceCharset
                $oStream.WriteText($_)
               
                $oStream.Position = 0
                $oStream.Charset  = $sDestCharset
                $oStream.ReadText()
               
                $oStream.Close()
        }
}

$sPath = "E:\Песочница\0269"

Get-ChildItem -Path $sPath\*.* -Include *.txt |`
    ForEach-Object -Process {
        if((Get-Content -Path $_ | StrConvert "windows-1251" "cp866") -match "^Сумм:\d+(?:\.\d)?[^\d.]*$") {
            $_ | Move-Item -Destination "E:\Песочница\0270"
        }
    }


Georgio 06-06-2013 22:18 2163494

Код:

@ECHO OFF
(
 ECHO Сумм:[0-9][0-9]
 ECHO Сумм:[0-9][0-9]\.[0-9]
)>temp.txt
FOR %%I IN ("E:\Folder 1\*") DO (
 FINDSTR /R /E /G:temp.txt "%%~I">nul&&^
COPY "%%~I" "E:\Folder 2\">nul
)
DEL temp.txt


Iska 07-06-2013 03:11 2163559

Georgio, почему не просто:
Код:

findstr.exe /r /e /c:"Сумм:[0-9][0-9]" /c:"Сумм:[0-9][0-9]\.[0-9]" "%%~i"
?

Georgio 07-06-2013 03:58 2163561

Iska, зта "сволочь", именуемая утилитой findstr.exe, никак не хочет напрямую воспринимать кириллицу. Ни смена кодовой страницы, ни перекодирование BAT-файла не приносят результата. Но, как видите, выход существует. Кстати, так и думал, что кто-нибудь спросит.

Iska 07-06-2013 07:34 2163580

У меня — воспринимает:
Код:

E:\Песочница\0269>chcp
Текущая кодовая страница: 866

E:\Песочница\0269>findstr.exe /r /e /c:"Сумм:[0-9][0-9]" /c:"Сумм:[0-9][0-9]\.[0-9]" E:\Песочница\0269\*.txt
E:\Песочница\0269\112.txt:Сумм:30
E:\Песочница\0269\112.txt:Сумм:10.1

? Windows XP SP3.

foma24 07-06-2013 09:51 2163618

Всем спасибо все прекрасно работает.

Подскажите еще, в том же файле еще есть строки вида <КоллПлат>45<\КоллПлат> с которыми нужно сделать тоже самое. На PS все прекрасно работает, а вот CMD не хочет воспринимать символы <> можно ли что то с этим сделать ?

Georgio 07-06-2013 10:13 2163627

Цитата:

Цитата foma24
нужно сделать тоже самое »

-- то есть оставить беэ изменения?

Если так, то сделаем.

foma24 07-06-2013 10:26 2163632

Простите что не уточнил. Лучше всего было бы и то и то. Т.е. тоже один батник ищет файлы с такой строкой в папке, другой батник корректирует файл и сохраняет в другой файл. Извините что надоедаю со своей проблемой

Georgio 07-06-2013 13:40 2163784

Код:

@ECHO OFF
ECHO ^<КоллПлат^>>temp.txt
FOR %%I IN ("E:\Folder 1\*") DO (
 FINDSTR /G:temp.txt "%%~I">nul&&^
COPY "%%~I" "E:\Folder 2\">nul
)
DEL temp.txt

Зтот BAT-файл будет искать в файлах строки, содержащие "<КоллПлат>" и, если таковые найдёт, то скопирует зтот файл в назначенную папку.

Второй BAT-файл, котрый будет обрабатывать такие файлы, дописываю.

Georgio 07-06-2013 17:21 2163932

Данный BAT-файл обрабатывает нужные файлы в пакетном режиме, причём обрабатываются все строки, включая и строки с угловыми скобками, так что необходимость в предыдущем BAT-файле может отпасть. Этот скрипт можно даже использовать сразу, без сортировки файлов, так как, если в файле не нужно делать замены, то такой файл будет переписан без изменений. Так что проверяйте.


Код:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
::Выставляем папку, файлы в которой нужно обработать (без кавычек):::
SET In=E:\Folder 1
::Выставляем папку (также без кавычек), в которую будут помещаться ::
::обработанные файлы (можно установить ту же самую папку, т. к. ::
::файлы будут сораняться с добавлением "_new" к старому имени):::
SET Out=E:\Folder 2
(
 FOR %%I IN ("%In%\*.txt") DO (
  FOR /F "usebackq tokens=*" %%J IN ("%%~I") DO (
    FOR /F "tokens=1,3 delims=:." %%K IN ("%%J") DO (
    IF %%K==Сумм (
      SET VAR1=%%L
      IF DEFINED VAR1 (
      SET VAR2=!VAR1:~1!
      IF DEFINED VAR2 (
        ECHO %%J>>"%Out%\%%~nI_new.txt"
    ) ELSE (
        ECHO %%J0>>"%Out%\%%~nI_new.txt"
  )) ELSE (
      ECHO %%J.00>>"%Out%\%%~nI_new.txt"
  )) ELSE (
      SET /P VAR="%%J" 0>nul 1>>"%Out%\%%~nI_new.txt"
      ECHO.>>"%Out%\%%~nI_new.txt"
)))))&&^
ECHO All's ready. Press any key to exit.&&PAUSE>nul


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


Ещё о некоторых нюансах.

1. Пустые строки не переписываются.
2. Пробелы в начале строк также не сохраняются.
3. Если строка целиком заключена в кавычки, то кавычки отбрасываются.
4. Если ещё вдруг что-нибудь заметите, сообщите.

Georgio 07-06-2013 18:51 2164008

Вложений: 1
Цитата:

Цитата Iska
У меня — воспринимает »

Цитата:

Цитата Iska
Windows XP SP3 »



Вот скрипт, который я протестировал в своей Windows 7 Starter:


Код:

CHCP
findstr.exe /r /e /c:"Сумм:[0-9][0-9]" /c:"Сумм:[0-9][0-9]\.[0-9]" "E:\Folder 1\111.txt"
findstr.exe /r /e /c:"‘㬬:[0-9][0-9]" /c:"‘㬬:[0-9][0-9]\.[0-9]" "E:\Folder 1\111.txt"
findstr.exe /G:"E:\Folder 1\111.txt" "E:\Folder 1\111.txt"

CHCP 1251
findstr.exe /r /e /c:"Сумм:[0-9][0-9]" /c:"Сумм:[0-9][0-9]\.[0-9]" "E:\Folder 1\111.txt"
findstr.exe /r /e /c:"‘㬬:[0-9][0-9]" /c:"‘㬬:[0-9][0-9]\.[0-9]" "E:\Folder 1\111.txt"
findstr.exe /G:"E:\Folder 1\111.txt" "E:\Folder 1\111.txt"

PAUSE>nul


Последние строки для каждой кодировки просто показывают содержимое файла.



А вот результат выполнения:


Файл 99938



Жаль, что в данный момент больше не на чем проверить, но, если мне не изменяет память, в тех версиях Windows XP и Windows Vista, на которых я работал, проблем с кириллицей для findstr.exe не было. Очевидно, в Windows 7 Starter другая редакция этой утилиты. Так что тот вариант скрипта универсален.

Iska 07-06-2013 19:10 2164027

Цитата:

Цитата Georgio
А вот результат выполнения: »

Почему не текстом?

Цитата:

Цитата Georgio
Вот скрипт…»

Кодировка его не OEM/866, а ANSI/1251, так?

Цитата:

Цитата Georgio
в тех версиях Windows XP … на которых я работал, проблем с кириллицей для findstr.exe не было. »

Были [выделение моё].

Georgio 07-06-2013 19:48 2164053

Цитата:

Цитата Iska
Почему не текстом? »

Вот текст:

Код:

E:\>CHCP
’ҐЄгй*п Є®¤®ў*п бва**Ёж*: 866

E:\>findstr.exe /r /e /c:"Сумм:[0-9][0-9]" /c:"Сумм:[0-9][0-9]\.[0-9]" "E:\Folde
r 1\111.txt"

E:\>findstr.exe /r /e /c:"‘㬬:[0-9][0-9]" /c:"‘㬬:[0-9][0-9]\.[0-9]" "E:\Folde
r 1\111.txt"

E:\>findstr.exe /G:"E:\Folder 1\111.txt" "E:\Folder 1\111.txt"
Сумм:30
Сумм:10.1
Сумм:50.03

E:\>CHCP 1251
Текущая кодовая страница: 1251

E:\>findstr.exe /r /e /c:"Сумм:[0-9][0-9]" /c:"Сумм:[0-9][0-9]\.[0-9]" "E:\Folde
r 1\111.txt"

E:\>findstr.exe /r /e /c:"‘㬬:[0-9][0-9]" /c:"‘㬬:[0-9][0-9]\.[0-9]" "E:\Folde
r 1\111.txt"

E:\>findstr.exe /G:"E:\Folder 1\111.txt" "E:\Folder 1\111.txt"
Сумм:30
Сумм:10.1
Сумм:50.03

E:\>PAUSE1>nul


Цитата:

Цитата Iska
Кодировка его не OEM/866, а ANSI/1251, так? »

Перекодировка BAT-файла в OEM/866 была сделана программой Штирлиц IV ("WIN в DOS"), а потом в него были добавлены неперекодированные строки. Кодировка файла 111.txt, конечно, ANSI/1251.


Цитата:

Цитата Iska
Были »

Спасибо за ссылку. Посмотрел. Есть даже решение, похожее на моё.

foma24 07-06-2013 20:18 2164062

Всем большое спасибо!!!

Iska 07-06-2013 20:33 2164073

Цитата:

Цитата Georgio
Вот текст: »

Ну, я просто выразил недоумение. Текст можно копировать, а картинку — нет. Потому я стараюсь приводить текст, а не скриншот (за исключением тех случаев, когда необходим именно он).


Цитата:

Цитата Georgio
Перекодировка в OEM/866 была сделана программой Штирлиц IV ("WIN в DOS"), а потом в этот BAT-файл были добавлены неперекодированные строки. »

Почему на скриншоте одна кодировка, а в приведённом тексте — другая?

Почему Вы не пользуетесь каким-нибудь подходящим редактором: Bred2/Bred3, AkelPad, Notepad++ и т.п.?

читать дальше »
Cам я пользую редактор Far Manager'a. В комплекте с плагинами «Colorer» и «[ESC] Editor's settings changer» он весьма удобен:



Цитата:

Цитата Georgio
Есть даже решение, похожее на моё. »

Там с другой целью: искать потребно было в ANSI. А тут нормально, в OEM.

Georgio 07-06-2013 21:29 2164092

Цитата:

Цитата Iska
Почему на скриншоте одно, а в тексте — другое? »

Вот поэтому и скриншот. Вот так копируется из командной строки.


Цитата:

Цитата Iska
Bred2/Bred3, AkelPad, Notepad++ »

Bred3, AkelPad, Notepad++, TigerPad, Штирлиц IV у меня в версиях "portable" и всегда под рукой (ярлыки в папке SendTo). Кстати, и WordPad в Windows 7 стал неплохим редактором, во всяком случае ANSI/1251 в OEM/866 и обратно перекодирует. Для такой перекодировки использую и свои BAT-файлы.


Цитата:

Цитата Iska
Cам я пользую редактор Far Manager'a. В комплекте с плагинами «Colorer» и «[ESC] Editor's settings changer» он весьма удобен »

Можно тоже попробовать.

Iska 07-06-2013 22:03 2164115

Цитата:

Цитата Georgio
Вот поэтому и скриншот. Вот так копируется из командной строки. »

Хмм… Не понимаю. А сделайте-ка перенаправление вывода того же пакетного файла в файл. И выложите этот файл вместе с пакетным файлом в архиве.

Цитата:

Цитата Georgio
Для такой перекодировки использую и свои BAT-файлы. »

Проще не перекодировать, а «напрямую» работать в потребной кодировке.

Georgio 07-06-2013 22:44 2164137

Цитата:

Цитата Iska
А сделайте-ка перенаправление вывода того же пакетного файла в файл. И выложите этот файл вместе с пакетным файлом в архиве. »


Тоже об зтом думал. Выкладываю:

Файл 99964

Iska 08-06-2013 11:13 2164288

Цитата:

Цитата Georgio
Выкладываю: »

Georgio:
Цитата:

Страница не найдена. Если вы уверены, что использовали правильную ссылку, свяжитесь с администрацией
:(.

Georgio 08-06-2013 12:08 2164313

Попытка №2.


Выкладываю:

Archive.7z


Время: 14:03.

Время: 14:03.
© OSzone.net 2001-