首页 > 解决方案 > 使用批处理脚本在 .csv 文件中组织行、列和值

问题描述

我在下面制作了这个脚本来组织我的.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

标签: batch-file

解决方案


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(最后一个“对”没有 a 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,因为使用了传统语法,并>>附加代替>创建)


推荐阅读