Код, чтобы взять количество других в строке строк - PullRequest
1 голос
/ 10 ноября 2019

Прежде чем начать, я бы включил эту ссылку на проблему в текстовый документ с выделенными текстами, чтобы проблема была намного понятнее


https://archive.org/download/batfile10112019/bat%20file%2010112019.rar


*0000000000003000345800483854651180013732112019              0
*000000000010004466170000003000083BOUBADJA SAFIA             1
*000000000010010346810000003110730BOUKHEMKHEM NABILA         1
*000000000010010694160000000000806ROUIBAH MESSAOUDA          1
*000000000010014708210000000000999SETILA AFAF                1
*000000000010024010600000003176161ZAITER EP BOUHAROUD SOUAD  1
*000000000010054726551524653176161BOULASSEL NORA             1

Предположим, у меня есть вышеуказанный текстовый файл, который содержит строки, длина каждой строки составляет 62 (комбинация символов и пробелов, вы можете проверить, поместив курсор перед символом «*» и посчитав до последнегохарактер). Я хочу сохранить заголовок как есть, но для других строк мне нужен командный файл (.bat), который будет делать следующее:

  1. Сохранить заголовок как есть (как якак указано выше).
  2. Из каждой суммы в строках будет взято 10,00 (денежная единица, будь то евро, доллар и т. д.), сумма каждой строки начинается с позиции «22» допозиция «34», поэтому сумма:

    • Вторая строка: 30000.83
    • Третья строка: 31107.30
    • Четвертая строка: 8.06
    • Пятая строка: 9.99
    • Шестая строка: 31761.61
    • Седьмая строка: 15246531761.61

Мы не можем взять 10,00 (долларов или евро или что-то еще ...) из сумм четвертой и пятой строк, которые равны 8,06 и 9,99 соответственно, поэтому пакетный файл сохранит их такими, какие они есть. Но для сумм второй, третьей, шестой и седьмой строки будут изменены следующие значения:

  • Вторая строка: 29990,83
  • Третья строка: 31097.30
  • Четвёртая строка: 8.06
  • Пятая строка: 9.99
  • Шестая строка: 31751.61
  • Седьмая строка: 15246531751.61

Таким образом, выходной файл будет выглядеть так:

*0000000000003000345800483854651180013732112019              0
*000000000010004466170000002999083BOUBADJA SAFIA             1
*000000000010010346810000003109730BOUKHEMKHEM NABILA         1
*000000000010010694160000000000806ROUIBAH MESSAOUDA          1
*000000000010014708210000000000999SETILA AFAF                1
*000000000010024010600000003175161ZAITER EP BOUHAROUD SOUAD  1
*000000000010054726551524653175161BOULASSEL NORA             1

У меня есть другая проблема, когда я имею дело с большим текстовым файлом (15000 строк)

Мне помог друг, нов коде были некоторые ошибки, поэтому я включил вышеуказанную ссылку в текстовый документ, чтобы увидеть сообщение об ошибке при работе с текстовыми файлами, которые содержат более 10000 строк.

код:

@echo off
setlocal enableextensions enabledelayedexpansion
chcp 28591 >nul

set nouveau=modified.txt

echo. > %nouveau%


for /f "usebackq delims=" %%A in ("original file.txt") do (

    set "line=%%A"
    set "index=!line:~-1!"

    if !index! EQU 1 (
        set "account=!line:~0,21!"
        set "amount=!line:~21,13!"
        set "number=!line:~21,9!"
        set "cut=!line:~30,4!"
        set "client=!line:~34!

        call :zeros amount

        if !amount! GEQ 1000 (
            set /a cut=!cut!-1000
            set cut=000!cut!
            set cut=!cut:~-4!
        )
        echo.!account!!number!!!cut!!client!

    ) else (echo.!line!)

) >> %nouveau%

exit


:zeros

set "chaine=!%1!"

for /L %%E in (0,1,12) do (
    if not "!chaine:~%%E,1!"=="0" (set "%1=!chaine:~%%E!" & goto :eof)
)

goto :eof

Я надеюсь, что я могу взять любую сумму с любой строки (10,00 в этом примере). Если я хочу изменить его на 5,00, можно ли просто изменить значение с 10,00 до 5,00 в предоставленном коде. заранее спасибо за любую помощь от вас, ребята

Ответы [ 3 ]

1 голос
/ 11 ноября 2019

У вас есть логический недостаток (последние четыре цифры используются только для расчета). Возможно, вы сделали это, чтобы обойти ограничение INT32 set /a, но в некоторых случаях это приведет к ложным результатам. Вы должны рассчитать всю сумму. Поскольку cmd не может сделать это, используйте помощь другого языка (здесь я выбрал PowerShell). Недостатком является низкая производительность, поскольку PowerShell необходимо загружать для каждого вычисления.

@echo off
setlocal enableextensions enabledelayedexpansion
chcp 28591 >nul

set nouveau=modified.txt
break> %nouveau%

(for /f "usebackq delims=" %%A in ("original file.txt") do (
  set "line=%%A"
  set "index=!line:~-1!"
  if !index! EQU 1 (
    set "account=!line:~0,21!"
    set "amount=!line:~21,13!"
    set "client=!line:~34!
    REM strip leading zeros:
    for /f "tokens=* delims=0" %%a in ("!amount!") do set cut=%%a
    if !cut! geq 1000 (
      for /f %%b in ('powershell "if (!cut! -ge 1000) {!cut!-1000} else {!cut!}"') do set "cut=0000000000000%%b"
      set cut=!cut:~-13!
    ) else set cut=!amount!
    echo !account!!cut!!client!
  ) 
))>"%nouveau%" 

goto :eof
0 голосов
/ 12 ноября 2019

Ваш исходный код не просто неправильный, но и очень неэффективный ... Чтобы выполнить вычитание с использованием 9-значного предела команды set /A, вы можете разделить операцию на две части: младший (справа)сторона) 7 цифр номера плюс оставшаяся 6 цифр верхней части (левая сторона). В результате получается чистый пакетный файл, который должен работать быстро даже при длине файла 15000 строк.

@echo off
setlocal EnableDelayedExpansion

rem "subtract" may have maximum 7 digits including two decimal digits
set "subtract=1000"
set "nouveau=modified.txt"

set "subtract=0000000%subtract%"
set "subtract=1%subtract:~-7%"

set /P "header=" < "original file.txt"

(
echo %header%

for /F "skip=1 usebackq delims=" %%A in ("original file.txt") do (

   set "line=%%A"
   set "high=1!line:~21,6!" & set "low=1!line:~27,7!"

   set /A "lowN=low-subtract" 
   if !lowN! geq 0 (
      set /A "low=10000000+lowN"
   ) else (
      set /A "highN=high-1000001"
      if !highN! geq 0 (
         set /A "high=1000000+highN, low=20000000+lowN"
      )
   )

   echo !line:~0,21!!high:~1!!low:~1!!line:~34!

)

) > "%nouveau%"
0 голосов
/ 11 ноября 2019

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

$Minus = 10.00
$LineNo = 1
Get-Content ".\original file.txt" | ForEach {
    If ($LineNo -Eq 1) {$_} ElseIf ($LineNo -GT 1) {
        [Decimal]$Decimal = $_.Substring(21,11)+"."+$_.Substring(32,2)
        If ($Decimal-$Minus -LT 0) {$Result = $_.Substring(21,13)} Else {
            $Result = (100*($Decimal-$Minus)).ToString("0000000000000")}
        $_.SubString(0,21)+$Result+$_.SubString(34)}
    $LineNo++} | Set-Content ".\modified.txt"

Просто настройте $Minus при необходимости.

Примечание: Get-Content может быть не самым быстрым методом, если ваши файлы очень большие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...