Организовать строки, столбцы и значения в CSV-файле с помощью пакетного сценария - PullRequest
0 голосов
/ 16 мая 2019

Я сделал этот скрипт ниже, чтобы организовать мой .csv файл.

Мой оригинальный файл 1.csv такой:

Central de Relacionamento;4002 5472 (todas as localidades);0800 570 8472 (exceto capitais)
Ouvidoria;0800 570 2288 (todas as localidades);Atendimento de segunda a sexta, das 8 às 18h. Exceto Feriados Nacionais.

Estabelecimento;Previsão de pagamento;Bandeira;Forma de pagamento;Quantidade de transações;Valor bruto;Valor líquido;
1050596258;02/05/2019;Elo;Crédito parcelado loja;1;R$ 37,05;R$ 35,90;
1050596258;02/05/2019;Elo;Débito à vista;1;R$ 15,90;R$ 15,67;
1050596258;06/05/2019;Elo;Crédito parcelado loja;1;R$ 19,98;R$ 19,36;
1050596258;06/05/2019;Elo;Débito à vista;3;R$ 277,40;R$ 273,37;
1050596258;06/05/2019;Visa;Crédito parcelado loja;1;R$ 27,46;R$ 25,95;
1050596258;08/05/2019;Elo;Débito à vista;1;R$ 69,90;R$ 68,89;
1050596258;13/05/2019;Elo;Débito à vista;5;R$ 608,60;R$ 599,78;
1050596258;17/05/2019;Elo;Crédito parcelado loja;1;R$ 16,63;R$ 16,11;
1050596258;20/05/2019;Elo;Crédito parcelado loja;1;R$ 27,95;R$ 27,08;
1050596258;21/05/2019;Elo;Crédito à vista;1;R$ 95,10;R$ 93,10;
1050596258;27/05/2019;Elo;Crédito à vista;1;R$ 55,70;R$ 54,53;
1050596258;29/05/2019;Elo;Crédito parcelado loja;1;R$ 24,40;R$ 23,64;
1050596258;10/06/2019;Elo;Crédito parcelado loja;1;R$ 30,88;R$ 30,00;
1050596258;13/06/2019;Elo;Crédito à vista;1;R$ 39,60;R$ 38,77;
1050596258;28/06/2019;Elo;Crédito parcelado loja;0;R$ 24,40;R$ 23,64;
1050596258;09/07/2019;Elo;Crédito parcelado loja;0;R$ 30,86;R$ 29,98;
1050596258;29/07/2019;Elo;Crédito parcelado loja;0;R$ 24,40;R$ 23,64;
1050596258;08/08/2019;Elo;Crédito parcelado loja;0;R$ 30,86;R$ 29,98;

И я хочу изменить его на это:

Previsão de pagamento   Bandeira     Valor líquido
02/05/2019              Elo          R$ 35,90
02/05/2019              Elo          R$ 15,67
06/05/2019              Elo          R$ 19,36
06/05/2019              Elo          R$ 273,37
06/05/2019              Vis          R$ 25,95
08/05/2019              Elo          R$ 68,89
13/05/2019              Elo          R$ 599,78
17/05/2019              Elo          R$ 16,11
20/05/2019              Elo          R$ 27,08
21/05/2019              Elo          R$ 93,10
27/05/2019              Elo          R$ 54,53
29/05/2019              Elo          R$ 23,64
10/06/2019              Elo          R$ 30,00
13/06/2019              Elo          R$ 38,77
28/06/2019              Elo          R$ 23,64
09/07/2019              Elo          R$ 29,98
29/07/2019              Elo          R$ 23,64
08/08/2019              Elo          R$ 29,98

Итак, я сделал этот скрипт ниже, но в результате получилось:

Previsão de pagamento~Bandeira~Valor líquido
02/05/2019~Elo~R$ 35,90
02/05/2019~Elo~R$ 15,67
06/05/2019~Elo~R$ 19,36
06/05/2019~Elo~R$ 273,37
06/05/2019~Visa~R$ 25,95
08/05/2019~Elo~R$ 68,89
13/05/2019~Elo~R$ 599,78
17/05/2019~Elo~R$ 16,11
20/05/2019~Elo~R$ 27,08
21/05/2019~Elo~R$ 93,10
27/05/2019~Elo~R$ 54,53
29/05/2019~Elo~R$ 23,64
10/06/2019~Elo~R$ 30,00
13/06/2019~Elo~R$ 38,77
28/06/2019~Elo~R$ 23,64
09/07/2019~Elo~R$ 29,98
29/07/2019~Elo~R$ 23,64
08/08/2019~Elo~R$ 29,98

Следуйте моему коду:

for /f  "skip=1 tokens=2 delims=" %%a in ("3.txt") do (
     sort /+27 < "3.txt" > "4.txt"
  )

Я думаю, & for /f впоследняя строка кода не верна.Кто-нибудь может мне помочь?

Спасибо


Редактировать 1:

Спасибо, ребята!Ваша помощь была очень полезна.

Я изменил свой сценарий ниже.Теперь я хотел отсортировать его по столбцу Bandeira, но не могу пропустить первую строку Previsão de pagamento Bandeira Valor líquido.

    @echo off
    setlocal EnableDelayedExpansion

    (for /f "skip=2 tokens=2,3,7 delims=;" %%a in (1.csv) do @echo %%a~ %%b~ %%c~)>2.csv

     SET "spaces=                                                            "
    (for /f "tokens=1,2,3 usebackq delims=~" %%i in ("2.csv") DO CALL :FORMAT "%%i" 25  "%%j"  14 "%%k") > 3.txt

    del /f /s /q 2.csv >nul
    GOTO :sorting

    :FORMAT
    SET "line="
    SET /a length=0
    :formlp
    IF "%2"=="" ECHO %line%%~1&GOTO :EOF
    SET /a length+=%2
    SET "line=%line%%~1%spaces%"
    CALL SET "line=%%line:~0,%length%%%"
    shift&shift&GOTO formlp

    :sorting

for /f  "skip=1 tokens=2 delims=" %%a in ("3.txt") do (
         sort /+27 < "3.txt" > "4.txt"
      )
pause

Ответы [ 4 ]

1 голос
/ 16 мая 2019
SET "spaces=                                                            "
(for /f "tokens=1,2,3 usebackq delims=~" %%i in ("2.csv") DO CALL :FORMAT "%%i" 25  "%%j"  14 "%%k") > 3.csv
GOTO :EOF

:FORMAT
SET "line="
SET /a length=0
:formlp
IF "%2"=="" ECHO %line%%~1&GOTO :EOF
SET /a length+=%2
SET "line=%line%%~1%spaces%"
CALL SET "line=%%line:~0,%length%%%"
shift&shift&GOTO formlp

Заменить последнюю строку кода на приведенную выше.

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

установить spaces как строку из нескольких пробелов.

прочитайте 2.csv, используя ~ в качестве разделителя и задав токены 1,2 и 3, затем передайте 3 "пары" параметров, являющихся "value" и field length, подпрограмме :format (последней) пара "не имеет field length)

Подпрограмма :format просто добавляет каждый параметр, без кавычек, к line, затем добавляет к результату большое количество пробелов, а call set ограничивает накопленное поле накопленным length, поэтому каждый пара дополняется по необходимости.

На последней «паре», %2 отсутствует и, следовательно, пусто, поэтому накопленная строка выводится вместе с параметром %1 (-quotes) и подпрограмма завершается.


Для сортировки :

Сначала создайте заголовок в 3.csv, отформатируйте в требуемые столбцы

(for /f "usebackqskip=2tokens=2,3,7 delims=;" %%i in ("1.csv") do CALL :FORMAT "%%i" 25  "%%j"  14 "%%k"&GOTO doneheader) > 3.csv
:doneheader

Затем отсортируйте содержимое csv.2 и , добавьте к заголовку уже в csv.3

(for /f "tokens=1,2,3 delims=~" %%i in ('sort /+11 "2.csv"') DO CALL :FORMAT "%%i" 25  "%%j"  14 "%%k") >> 3.csv

(примечание usebackq, поскольку используется обычный синтаксис, и >> для добавления вместо > для создания)

0 голосов
/ 16 мая 2019
@echo off
setlocal enabledelayedexpansion

(for /f "skip=2 tokens=2,3,7 delims=;" %%a in (1.csv) do (
  set "a=%%a                      "
  set "b=%%b          "
  for /f "tokens=1,*" %%m in ("%%c") do (set "c=%%m" & set "d=   %%n")
  echo !a:~0,22!!b:~0,10!!c!!d:~-7!
))>2.csv
<2.csv set /p header=
(echo %header%
more +1 2.csv |sort /+32) >3.csv

Выход:

Previsπo de pagamento Bandeira  Valorlφquido
02/05/2019            Elo       R$  15,67
17/05/2019            Elo       R$  16,11
06/05/2019            Elo       R$  19,36
28/06/2019            Elo       R$  23,64
29/05/2019            Elo       R$  23,64
29/07/2019            Elo       R$  23,64
06/05/2019            Visa      R$  25,95
20/05/2019            Elo       R$  27,08
08/08/2019            Elo       R$  29,98
09/07/2019            Elo       R$  29,98
10/06/2019            Elo       R$  30,00
02/05/2019            Elo       R$  35,90
13/06/2019            Elo       R$  38,77
27/05/2019            Elo       R$  54,53
08/05/2019            Elo       R$  68,89
21/05/2019            Elo       R$  93,10
06/05/2019            Elo       R$ 273,37
13/05/2019            Elo       R$ 599,78
0 голосов
/ 16 мая 2019

Вот возможный подход к достижению желаемого - см. Все пояснительные rem замечания в коде:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE=%~1"   & rem // (input file; `%~1` is first command line argument)
set /A "_PADL=24" & rem // (number of spaces to pad the left token 2 with)
set /A "_PADM=13" & rem // (number of spaces to pad the mid token 3 with)
set /A "_PADR=0"  & rem // (number of spaces to pad the right token 7 with)
                    rem // (`0` defines not to pad with spaces to the right)

rem // Store current code page, then change it to maintain extended characters:
for /F "tokens=2 delims=:" %%P in ('chcp') do set "$CP=%%P"
> nul chcp 437

rem // Build string of padding spaces:
set /A "NUM=_PADL|_PADM|_PADR"
set "SPC=" & setlocal EnableDelayedExpansion
for /L %%S in (1,1,%NUM%) do set "SPC=!SPC! "
endlocal & set "SPC=%SPC%"

rem // Read input file, extract certain tokens and output them right-space-padded:
for /F "usebackq skip=3 tokens=2,3,7 delims=; eol=;" %%A in ("%_FILE%") do (
    set "LEFT=%%A" & set "MID=%%B" & set "RIGHT=%%C"
    setlocal EnableDelayedExpansion
    if %_PADL% gtr 0 set "LEFT=!LEFT!%SPC%" & set "LEFT=!LEFT:~,%_PADL%!"
    if %_PADM% gtr 0 set "MID=!MID!%SPC%" & set "MID=!MID:~,%_PADM%!"
    if %_PADR% gtr 0 set "RIGHT=!RIGHT!%SPC%" & set "RIGHT=!RIGHT:~,%_PADR%!"
    echo(!LEFT!!MID!!RIGHT!
    endlocal
)

rem // Restore original code page:
> nul chcp %$CP%

endlocal
exit /B

Учитывая, что скрипт сохраняется как rearrange-data.bat, а входной файл называется 1.csv, запустите скрипт следующим образом:

rearrange-data.bat "1.csv"

Чтобы записать выходные данные в файл с именем 2.csv, а не отображать его в консоли, используйте следующую командную строку:

rearrange-data.bat "1.csv" > "2.csv"
0 голосов
/ 16 мая 2019

Это прекрасная возможность использовать мою утилиту командной строки для регулярных выражений JREPL.BAT . Это чистый скрипт (гибридный JScript / batch), который изначально запускается на любом компьютере с Windows начиная с XP. И это намного быстрее, чем любое «чистое» пакетное решение.

jrepl "[^;]*;([^;]*);([^;]*);(?:[^;]*;){3}([^;]*);" "$txt=rpad($1,24)+rpad($2,13)+$3" /jmatchq /f input.csv /o output.txt

Первые 3 строки не соответствуют поисковому выражению, поэтому опция /JMATCHQ исключает их из вывода. Но если у вас действительно есть начальные строки, которые совпадают, но вы хотите исключить их, то вы можете явно исключить их с помощью опции /EXC.

jrepl "[^;]*;([^;]*);([^;]*);(?:[^;]*;){3}([^;]*);" "$txt=rpad($1,24)+rpad($2,13)+$3" /jmatchq /exc 1:3 /f input.csv /o output.txt

Если бы я был вынужден решить эту проблему с помощью чистой партии, то я бы использовал

@echo off
setlocal enableDelayedExpansion
set "sp=                                                        "
>"output.txt" (
  for /f "usebackq skip=3 tokens=2,3,7 delims=;" %%A in ("input.csv") do (
    set "C1=%%A%sp%"
    set "C2=%%B%sp%"
    echo !C1:~0,24!!C2:~0,13!%%C
  )
)

Но приведенный выше код имеет следующие ограничения:

  • В данных не должно быть никаких !. Это легко решается включением и выключением отложенного расширения в цикле.
  • Не должно быть пустых столбцов, кроме, возможно, последнего столбца. Это очень трудно решить с помощью чистой партии.

Другие ограничения, которые могут возникнуть, если вы попытаетесь обобщить эту пакетную технику:

  • Каждая строка ввода должна иметь длину <= 8191 байт. Не совсем разрешимо с чистой партией. </li>
  • Вы не можете получить доступ к столбцам 32 или дальше. Эту проблему можно решить, используя чистый пакет с большим количеством тупого, сложного кода.
  • Значения в кавычках не должны содержать разделитель ;. Это очень трудно решить с помощью чистой партии.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...