将数据添加到数据库的 Linux bash 脚本

标签 linux bash awk scripting mariadb

我正在尝试编写一个 bash 脚本,该脚本将从 csv 文件中提取数据并将其放入我可以将其放入数据库的格式。 csv 文件大约有 1000 行和 8 列。当我使用命令行时,我可以获得完全按照我想要的格式格式化的数据。我正在使用最新版本的 CentOS 最小安装。

(编辑)csv 文件的示例是:

[root@node72 ~]# cat users72.csv | head

msza907,Matyas Szabo,Men,Fencing,FE,germany

krut825,Kristian Ruth,Men,Sailing,SA,norway

sdon251,Samuil Donkov,Men,Shooting,SH,bulgaria

aroa777,Andres Roa,Men,Football,FB,colombia

我在 CLI 中使用的代码是:

# cat users72.csv | awk -F',' '{ print "INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES (""\""$1"\""", ""\""$3"\""", ""\""$5"\""");"}'

输出示例如下所示:

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES ("gjan887", "Men", "AR");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES ("ifet740", "Women", "VO");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES ("apet755", "Men", "AT");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES ("fnep723", "Men", "SH");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES ("othi288", "Women", "BK");

这个语法对于 mysql 来说并不完全正确,因为我需要一个 ID 号,而这正是我使用脚本的目的。 ID 号必须按奇数递增,因此 1、3、5 等。我的脚本的问题是,当我运行它并将其保存到一个文件中时,我计划使用它来将数据导入数据库,它打印一行带有 id 和用户名,然后下一行包含我不需要的其他数据,我能弄明白。

下面是我的脚本:

#!/bin/bash
inputData=$(cat /root/users72.csv);
((id=1))
for athleteTable in $inputData
do
    echo "$athleteTable" | awk -F',' '{ print "INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES ('$id', " "\""$1"\"" ", " "\""$3"\"" ", " "\""$5"\""");"}'
    ((id=id+2))
done > /root/users72.sql

users72.sql 文件的示例如下所示:

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES (1, "msza907", "", "");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES (3, "Szabo", "Fencing", "germany");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES (5, "krut825", "", "");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES (7, "Ruth", "Sailing", "norway");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES (9, "sdon251", "", "");

INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES (11, "Donkov", "Shooting", "bulgaria");

在过去的 7 个小时里,我一直在用头撞墙,试图让它工作,改变语法检查其他示例,我开始认为操作系统中存在故障。如果有人知道哪里出了问题或知道完成此任务的更简单方法可以帮助我,我会很高兴。提前谢谢你。

最佳答案

我肯定同意@GhostCat 的观点,解析 CSV 比仅用逗号分隔要复杂得多,尽管一些简单的 CSV 可能会起作用。不过,CSV 通常可以在字段中包含逗号,因此按逗号拆分会破坏内容。

就是说,您的问题是为什么脚本没有按照您的意愿执行,是您让文件内容发生分词并尝试 awk 每个“单词”。您应该只增加 awk 中的计数器,让它为您读取文件。假设您对原始的 awk 命令感到满意,您可以这样做:

 awk -F',' 'BEGIN {id=1} {print "INSERT INTO athletes (id, username, gender, sport_abbreviation) VALUES ( " id " \47"$1"\47, \47"$3"\47, \47"$5"\47);";id+=2}' users72.csv

我们在其中创建了一个本地 id 变量,并且每行将其递增 2。我还使用八进制转义在每个字段周围打印单引号,而不是像您一直在做的那样使用大量引号和转义符。如果您愿意,请随时返回您的方式(或者如果您需要,请使用 \42 作为双引号)。最后,我将其更改为 awk 只打开文件本身,我们可以避免 cat 和管道。

关于将数据添加到数据库的 Linux bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39929980/

相关文章:

linux - bash 脚本如何确保运行的副本不超过一个?

regex - Bash - 从不包含特定模式的文件中获取行

c - 在Linux上运行C语言程序时遇到问题

linux - 控制台上的 SSH 谷歌云权限被拒绝(公钥),并出现 google-cloud-sdk 文件错误

linux - 为什么 "rm"命令会覆盖bash脚本的显示

linux - 如何在 Linux 中将数字数据从文件复制到数组

perl - 当标题匹配多个文件时连接列值

linux - 计算 TCP 重传

linux - 如何更改 linux/unix 文本文件中的日期格式

regex - AWK:如果这是一个正则表达式,有没有办法将 OFS 设置为 FS?