Войти

Показать полную графическую версию : [решено] Добавление числа после точки с условием


Страниц : [1] 2

foma24
06-06-2013, 15:01
Добрый день. Помогите решить такую задачу. Есть файл 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
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
Большое спасибо, только небольшое уточнение, нужно чтобы батник обрабатывал только строки с началом Сумм, т.е. например если в строке будет не Сумм:30 а Итог:30 то такую строку трогать не нужно, она должна в первозданном виде сохраниться в файл 222.txt

Iska
06-06-2013, 16:31
Есть файл 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
Кодировку файла укажите. »

OEM866

Iska
06-06-2013, 17:40
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
@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
Огромное спасибо все прекрасно работает.

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

Iska
06-06-2013, 19:03
Кодировка та же? Пробуйте:
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
@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
Georgio, почему не просто:
findstr.exe /r /e /c:"Сумм:[0-9][0-9]" /c:"Сумм:[0-9][0-9]\.[0-9]" "%%~i"
?

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

Iska
07-06-2013, 07:34
У меня — воспринимает:
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
Всем спасибо все прекрасно работает.

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

Georgio
07-06-2013, 10:13
нужно сделать тоже самое » -- то есть оставить беэ изменения?

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

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

Georgio
07-06-2013, 13:40
@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
Данный 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
У меня — воспринимает »
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
А вот результат выполнения: »
Почему не текстом?

Вот скрипт…»
Кодировка его не OEM/866, а ANSI/1251, так?

в тех версиях Windows XP … на которых я работал, проблем с кириллицей для findstr.exe не было. »
Были (http://forum.script-coding.com/viewtopic.php?pid=63919#p63919) [выделение моё].




© OSzone.net 2001-2012