Unix:从.dat文件中提取数据并插入SQL数据库?

时间:2016-04-20 17:56:14

标签: bash shell unix grep extract

嗨所以我需要处理大约1000个.dat文件,每个文件都有大约1,000个用户的数据。文件格式如下(实际上,数据当然填写为:John,18,john @email.com例如 - 我只编号以突出显示订购问题):

<Name> Name_1
<Age> Age_1 
<Email> Email_1

<Name> Name_2
<Age> Age_2
<Email> Email_2

(...etc...)

所以假设我有一个数据库表,有两个颜色(名称和电子邮件),对我来说,使用Unix / Shell / Bash提取数据和填充数据库的最佳方法是什么?目前我正在使用以下内容来尝试提取数据:

for file in $1/*;
do
    grep "<Name>" $file |
    sed 's/<Name>//g' >> temp.txt

    grep "<Email>" $file |
    sed 's/<Email>//g'>> temp.txt
done

虽然这会提取正确的数据,但输出结果如下:

(--File 1--)
Name_1
Name_2
Email_1
Email_2
(--File 2--)
Name_1001
Name_1002
Email_1001
Email_1002
(etc)

实际上,我认为如果我可以按照这个顺序提取数据会更好,但我不知道是否可以使用grep。

Name_1
Email_1

Name_2
Email_2

(etc)

因为如果像这样提取数据,那么我可以将值存储在shell变量中,然后使用以下内容添加到数据库中:

sqlite db.sql INSERT INTO users VALUES ($name, $email);

或者这些方面的东西,如果那样的话。

无论如何,希望我已经半清楚地解释了自己,但是如果有人能帮我解决这个问题,我会非常感激。实际上,我问是否有可能grep一个用户,然后是电子邮件,然后是另一个用户和相应的电子邮件...而不是grep似乎工作,通过提取所有用户,然后提取所有电子邮件。也许有另一个功能可以很好地完成这项工作?

干杯!

3 个答案:

答案 0 :(得分:2)

<body>grep这不是一个好问题。我推荐sed未经测试首次剪切:

awk

您也可以尝试

awk '
/<Name>/ {name=$1}
/<Email>/ {emails[name] = $1}

END {for (n in emails) {print n, print email[n]}}
' *.dat

答案 1 :(得分:1)

好像你是grep的粉丝。试一试:

grep -Po '(?<=(Name|mail)>[\t\s])(.*)$' file | `xargs -n2 printf "sqlite db.sql INSERT INTO users VALUES (%s, %s)\n"`

第一部分是做一个积极的观察,以获取相关信息。 Lookbehind不支持varibale长度,这就是使用mail代替Email的原因。它输出:

Name_1
Email_1
Name_2
Email_2

xargs -n2将姓名和电子邮件合并如下:

Name_1 Email_1
Name_2 Email_2

这是由printf格式化并正在执行。希望它有所帮助。

现在请不要告诉我你的grep不支持-P; - )

答案 2 :(得分:0)

你可以在(GNU)sed中完成,尽管awk脚本要简单得多。

<强> dat2sql.sed:

/<NAME>/I H  # store name
/<EMAIL>/I {
  H;         # store email
  g          # get stored strings

  s/<[^>]+>\s+//gI; # remove <NAME> and <EMAIL>

  s/^$\n/sqlite db.sql INSERT INTO users VALUES ("/;
  s/\n/", "/;
  s/$/" );/;

  p                 # print results
  s/.*//g;  x;      # clear hold space
} 

像这样使用:sed -rn -f dat2sql.sed your_file

前提条件是Name在文件中的每条记录的电子邮件之前。