【问题标题】:Bash: Base64 encode 1 column in a very large .csv and output to new fileBash:Base64 在一个非常大的 .csv 中编码 1 列并输出到新文件
【发布时间】:2017-11-03 21:48:18
【问题描述】:

我尝试使用下面的代码,但 csv 文件有超过 8000 万行(大约 25gb),并且一些特殊字符似乎会破坏 echo 命令。 csv 有 2 列,用逗号分隔。 例如:

blah, blah2
data1,data2
line3,fd$$#$%T%^Y%&$$B
somedata,%^&%^&%^&^

目标是获取第二列,base64 是准备导入 sql 数据库。我正在第二列上进行 base64 编码,因此支持 unicode 等,并且没有字符会损坏数据库。 我正在寻找一种不会破坏特殊字符等的更有效的方法。

awk -F "," '
    {
        "echo "$2" | base64" | getline x
        print $1, x
    }
' OFS=',' input.csv > base64.csv

错误:

sh: 1: Syntax error: word unexpected (expecting ")") : 
not foundrf :
not found201054 : 
not foundth : 
not foundz09  
| base64' (Too many open files)ut.csv FNR=1078) fatal: cannot open pipe `echo q1w2e3r4

【问题讨论】:

  • 我发现的另一个问题是第二列也可能在数据中包含逗号。无论如何要解决这个问题?

标签: mysql bash csv base64


【解决方案1】:

问题是您没有在 awk 脚本中引用 echo 的参数。

不过这个不用awkbash可以直接解析文件。

IFS=, while read -r col1 col2
do
    base64=$(base64 <<<"$col2")
    echo "$col1, $base64"
done < input.csv > base64.csv

【讨论】:

  • 出现错误:./base64.sh:第 2 行:while:找不到命令 ./base64.sh:第 3 行:意外标记附近的语法错误 do' ./base64.sh: line 3: do'
  • 找不到while命令的任何原因,它是一个内置命令。
  • 当我搜索该错误的其他示例时,它们总是由于某种拼写错误。
【解决方案2】:

在您的 MySQL 命令行客户端中尝试这样的操作:

LOAD DATA LOCAL '/tmp/filename.txt' INTO TABLE tbl FIELDS TERMINATED BY ','

如果需要,您可以对字段重新排序,如果需要删除特殊字符、连接字符串、转换日期格式等,可以应用特殊表达式。如果您仍然需要 base64 转换,MySQL 5.6 及更高版本有一个本机函数( TO_BASE64()),而旧的有一个 UDF。见base64 encode in MySQL

但是,只要您的列没有逗号,LOAD DATA INFILE 就可以处理它,并且您可以通过避免转换来节省一些磁盘空间。

有关如何使用 LOAD DATA INFILE 的详细信息,请参阅 MySQL 手册:https://dev.mysql.com/doc/refman/5.7/en/load-data.html

您需要以具有 LOAD 权限的用户身份向 MySQL 进行身份验证,并启用 local-infile 选项(例如,通过在命令行上传递 --local-infile=1

【讨论】:

  • 这对于包含输入和转换以及开销等的庞大数据集的工作情况如何
  • 如果不使用 C 语言编写您自己的定制输入转换器,开销大约是尽可能低的。实际上,您几乎无法在基准测试中对其进行测量,除非它是非常非常复杂。如果没有实现您自己定制的低级表空间导入器,您无法用其他任何东西击败它。
【解决方案3】:

目标是采用 second 列和 base64

awkgetline功能:

awk -F',[[:space:]]*' '{ cmd="echo \042"$2"\042 |  base64"; cmd | getline v; 
        close(cmd); print $1","v }' input.csv > base64.csv

base64.csv 内容(用于您当前的输入):

blah,YmxhaDIK
data1,ZGF0YTIK
line3,ZmQyNzMwOCMkJVQlXlklJjI3MzA4Qgo=
somedata,JV4mJV4mJV4mXgo=

【讨论】:

  • 我不清楚输出 col1,col2 是否输出为 col1,base64col2。你只输出base64的第二列
猜你喜欢
  • 1970-01-01
  • 2014-08-11
  • 1970-01-01
  • 2010-09-30
  • 2012-08-16
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多