【问题标题】:Process non common csv file with awk using field patterns使用字段模式使用 awk 处理非常见 csv 文件
【发布时间】:2020-07-27 01:32:39
【问题描述】:

我的银行使用; 作为字段分隔符和二进制代码(十六进制a0 或八进制240)发送一个非常见的CSV 文件以包含; 可能出现的字段,如下所示:

输入

Extrait;Date;Date valeur;Compte;Description;Montant;Devise
�2020/0001/0002�;29.02.2020;29.02.2020;-;�28/02/20 Some shop in Antwerp     A Antwerpen (BE)�;-16,50;EUR
�2020/0001/0001�;01.02.2020;01.02.2020;-;�31/01/20 Some shop in Zaventem    Z Zaventem (BE)�;-13,00;EUR

我需要使用 AWK 处理字段 2、5 和 6。

期望的输出

{Date}{Description}{Montant}
{29.02.2020}{28/02/20 Some shop in Antwerp     A Antwerpen (BE)}{-16,50}
{01.02.2020}{31/01/20 Some shop in Zaventem    Z Zaventem (BE)}{-13,00}

到目前为止,只要 包围的字段不包含任何;,下面使用变量FPAT 的脚本就可以工作:

#!/usr/bin/awk -f
BEGIN { 
  FS=";"
  FPAT="[^;]*"                        # this works but not in all cases
  #FPAT="([^;]*)|(\240[^\240]+\240)"  # this doesn't work
}
{ gsub (/\240/, "", $5)               # I wish I could skip this instruction too
  print "{" $2 "}{" $5 "}{" $6 "}" 
}

我发现了一个类似的案例(请参阅awk FPAT to ignore commas in csv),但将, 更改为; 并将\" 更改为\240 并没有成功。

我需要帮助来实施 FPAT 模式以在所有情况下正确扫描我的 CSV 文件。

【问题讨论】:

  • 请注意,csv 格式不是标准格式,即使逗号作为分隔符和双引号作为保护字符更常见,使用分号和不可破坏字符也没有错空间。另外,请注意不可破坏的空间,可能还有所有文件,都是用 ISO8859-1 编码而不是 UTF-8 编写的。
  • @CasimiretHippolyte:好的,我将编辑我的问题,以便将“非标准”更改为“非常见”。我不知道文件是 UTF-8 还是 ISO8859-1 编码的,因为我看不到带重音的字母。
  • @CasimiretHippolyte:确实,我在另一个文件中看到我的银行正在根据 ISO8859-1 进行编码。如果我将文件转换为 UTF-8,我会得到序列 \xc2\xa0 而不是 \xa0,我不能在 anubhava 提出的 FPAT 中使用它。我将不得不找到一种解决方法......
  • 没有禁止将anubhava脚本的结果编码为UTF-8之后。
  • 另外,如果您之前选择转换文件,您可以将 FPAT 更改为 [^;\xc2]+(\xc2[^\xa0][^;\xc2]*)*|(\xc2[^\xa0][^;\xc2]*)+ (不要打错字)

标签: regex csv awk


【解决方案1】:

您可以将此gnu awkFPAT 一起使用:

awk -v FPAT='[^;\xa0]+' '{printf "{%s}{%s}{%s}\n", $2, $5, $6}' file

{Date}{Description}{Montant}
{29.02.2020}{28/02/20 Some shop in Antwerp     A Antwerpen (BE)}{-16,50}
{01.02.2020}{31/01/20 Some shop in Zaventem    Z Zaventem (BE)}{-13,00}

-v FPAT='[^;\xa0]+' 将字段模式设置为除 ;\xa0 以外的任何字符的 1+。

【讨论】:

  • 它有效,谢谢,但我仍然需要添加一个声明 gsub (/\xa0/, "", $5) 以摆脱二进制字符。我在FPAT 中将+ 更改为* 以匹配空字段。
  • 毕竟,我认为将FPAT 设置为[^;\xa0]* 会将包含在\xa0 中的字符串分成两部分,因为它包含;,这是我想要避免的。
  • 由于正则表达式是[^;\xa0]+,它将使;\xa0 成为单个分隔符而不是2 个分隔符。但是,我无法从您有问题的输入中真正弄清楚\xa0 的位置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
相关资源
最近更新 更多