【发布时间】:2019-09-07 11:12:25
【问题描述】:
我想使用 bash 脚本首先将文件从 google 驱动器复制到本地驱动器并重命名(删除空格并添加前缀),然后将这些 .csv 文件导入 mysql 数据库。这些 .csv 有不同的列,所以我需要从每个 .csv 中获取列名并使用这些列名创建一个表,然后导入数据。
我将不胜感激。
我在这里找到了一些代码https://ericlondon.com/2011/04/10/a-bash-shell-script-to-import-a-large-number-of-csv-files-into-mysql.html,我已经对其进行了修改,但我无法让它工作。我承认我不明白这一切是做什么的。
这是我目前的脚本:
#!/bin/bash
# show commands being executed, per debug
set -x
# define database connectivity
_db="dbname"
_db_user="user"
_db_password="password"
# delete existing files
rm -rf /path/to/*.csv
# copy files to local disk
cp /old/path/to/*.csv /path/to/
# define directory containing CSV files
_csv_directory="/path/to"
# go into directory
cd $_csv_directory || exit
# edit file name
rename "s/ //g" *.csv
rename "s/^/tp/g" *.csv
# get a list of CSV files in directory
_csv_files=`ls -1 *.csv`
# loop through csv files
for _csv_file in ${_csv_files[@]}
do
# remove file extension
_csv_file_extensionless=`echo "$_csv_file" | sed 's/\(.*\)\..*/\1/'`
# define table name
_table_name="${_csv_file_extensionless}"
# get header columns from CSV file
_header_columns=`head -1 $_csv_directory/$_csv_file | tr ',' '\n' | sed 's/"//' | sed 's/ /_/g'`
_header_columns_string=`head -1 $_csv_directory/$_csv_file | sed 's/ /_/g' | sed 's/"//g' | sed 's/(//g' | sed 's/)//g'`
# ensure table exists
mysql -u $_db_user -p$_db_password $_db << eof
CREATE TABLE IF NOT EXISTS \`$_table_name\` ENGINE=MyISAM DEFAULT CHARSET=utf8
eof
# loop through header columns
for _header in "${_header_columns[@]}"
do
# add column
mysql -u $_db_user -p$_db_password $_db --execute="alter table \`$_table_name\` add column IF NOT EXISTS \`$_header\` text"
done
# import csv into mysql
mysqlimport --fields-enclosed-by='"' --fields-terminated-by=',' --lines-terminated-by="\r\n" --columns=$_header_columns_string -u $_db_user -p$_db_password $_db $_csv_directory/$_csv_file
done
exit
这是我为每个 .csv 获得的更新输出:
++ for _csv_file in ${_csv_files[@]}
+++ echo tpTriplexBC.csv
+++ sed 's/\(.*\)\..*/\1/'
++ _csv_file_extensionless=tpTriplexBC
++ _table_name=tpTriplexBC
+++ head -1 /path/to/tpTriplexBC.csv
+++ tr , '\n'
+++ sed 's/^"//'
+++ sed 's/"$//'
+++ sed 's/ /_/g'
+++ sed 's/(//g'
+++ sed 's/)//g'
++ _header_columns='ProductName
ProductID
Quantity
Tax
Paper_Type
PriceExpress
Production_Days_Express
PriceStandard
Production_Days_Standard
PriceSaver
Production_Days_Saver
PriceSameday
Production_Days_Sameday
Price_Just_Print
Price_File_Check
Price_File_Check_with_Proofing
Price_File_Assist
Artwork_Tax
Size
Flat_Width_mm
Flat_Height_mm
Finished_Width_mm
Finished_Height_mm
productionDataJSON
'pdatedAt"
+++ head -1 /path/to/tpTriplexBC.csv
+++ sed 's/ /_/g'
+++ sed 's/"//g'
+++ sed 's/(//g'
+++ sed 's/)//g'
++ _header_columns_string=$'ProductName,ProductID,Quantity,Tax,Paper_Type,PriceExpress,Production_Days_Express,PriceStandard,Production_Days_Standard,PriceSaver,Production_Days_Saver,PriceSameday,Production_Days_Sameday,Price_Just_Print,Price_File_Check,Price_File_Check_with_Proofing,Price_File_Assist,Artwork_Tax,Size,Flat_Width_mm,Flat_Height_mm,Finished_Width_mm,Finished_Height_mm,productionDataJSON,updatedAt\r'
++ mysql -u user -ppassword dbname
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `ProductName` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `ProductID` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Quantity` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Tax` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Paper_Type` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `PriceExpress` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Production_Days_Express` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `PriceStandard` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Production_Days_Standard` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `PriceSaver` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Production_Days_Saver` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `PriceSameday` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Production_Days_Sameday` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Price_Just_Print` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Price_File_Check` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Price_File_Check_with_Proofing` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Price_File_Assist` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Artwork_Tax` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Size` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Flat_Width_mm` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Flat_Height_mm` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Finished_Width_mm` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `Finished_Height_mm` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexBC` ADD COLUMN IF NOT EXISTS `productionDataJSON` text'
++ for _header in ${_header_columns[@]}
++ mysql -u user -ppassword dbname '--execute=ALTER TABLE `tpTriplexB` text'COLUMN IF NOT EXISTS `updatedAt"
'RROR 1166 (42000) at line 1: Incorrect column name 'updatedAt"
++ mysqlimport '--fields-enclosed-by="' --fields-terminated-by=, '--lines-terminated-by=\n' $'--columns=ProductName,ProductID,Quantity,Tax,Paper_Type,PriceExpress,Production_Days_Express,PriceStandard,Production_Days_Standard,PriceSaver,Production_Days_Saver,PriceSameday,Production_Days_Sameday,Price_Just_Print,Price_File_Check,Price_File_Check_with_Proofing,Price_File_Assist,Artwork_Tax,Size,Flat_Width_mm,Flat_Height_mm,Finished_Width_mm,Finished_Height_mm,productionDataJSON,updatedAt\r' -u user -ppassword dbname /path/to/tpTriplexBC.csv
mysqlimport: Error: 1054, Unknown column 'updatedAt' in 'field list', when using table: tpTriplexBC
++ exit
列被插入到每个表中,但没有数据。还创建了我不想要的名为 -1 和 ls 的表。
csv 的第一行是:
"ProductName","ProductID","Quantity","Tax","Special Finish","Laminate","Sides Printed","Material","PriceStandard","Production Days Standard","PriceSaver","Production Days Saver","PriceSameday","Production Days Sameday","Price Just Print","Price File Check","Price File Check with Proofing","Price File Assist","Artwork Tax","Size","Flat Width (mm)","Flat Height (mm)","Finished Width (mm)","Finished Height (mm)","productionDataJSON","updatedAt"
标头的八进制转储输出:
0000000 " P r o d u c t N a m e " , " P
0000020 r o d u c t I D " , " Q u a n t
0000040 i t y " , " T a x " , " P a p e
0000060 r T y p e " , " P r i c e E x
0000100 p r e s s " , " P r o d u c t i
0000120 o n D a y s E x p r e s s "
0000140 , " P r i c e S t a n d a r d "
0000160 , " P r o d u c t i o n D a y
0000200 s S t a n d a r d " , " P r i
0000220 c e S a v e r " , " P r o d u c
0000240 t i o n D a y s S a v e r "
0000260 , " P r i c e S a m e d a y " ,
0000300 " P r o d u c t i o n D a y s
0000320 S a m e d a y " , " P r i c e
0000340 J u s t P r i n t " , " P r
0000360 i c e F i l e C h e c k " ,
0000400 " P r i c e F i l e C h e c
0000420 k w i t h P r o o f i n g "
0000440 , " P r i c e F i l e A s s
0000460 i s t " , " A r t w o r k T a
0000500 x " , " S i z e " , " F l a t
0000520 W i d t h ( m m ) " , " F l a
0000540 t H e i g h t ( m m ) " , "
0000560 F i n i s h e d W i d t h (
0000600 m m ) " , " F i n i s h e d H
0000620 e i g h t ( m m ) " , " p r o
0000640 d u c t i o n D a t a J S O N "
0000660 , " u p d a t e d A t " \r \n
【问题讨论】:
-
通读脚本并尝试了解每个步骤的作用并了解每个命令中使用的选项将是一个很好的练习。您将学到很多东西并提高您的总体技能。
-
在您的跟踪输出中,您是否研究过错误消息?有些东西看起来不对:
...NOT EXISTS `updatedAt"以双引号而不是一个反引号结尾。下一行显示'RROR... Incorrect column name 'updatedAt"。我怀疑您的for _header in...将最后一个标题名称设为updatedAt"。您还可以在跟踪中显示的标题列表中看到它。在 bash 中,如果您执行for "a b c" ...,您将获得"a、b和c"作为循环变量。 -
我已经设法修复了关于未知列 Flat_Width_mm 的错误 1054,但“updatedAt”错误仍然存在,我不明白为什么它将标题读取为“pdatedAt”而不是 updateAt。它在csv 文件中的相同格式。我认为它与这一行有关(我已从上面编辑以修复另一个错误):_header_columns=
head -1 "$_csv_directory/$_csv_file" | tr ',' '\n' | sed 's/^"//' | sed 's/"$//' | sed 's/ /_/g' | sed 's/(//g' | sed 's/)//g'但我看不出是什么原因造成的 -
能否请您显示 CSV 文件的第一行?看起来您的列名都没有包含空格,所以我不确定为什么您的替换列表中有
s/ /_/g,除非您进行概括。转出_header_columns的样子。 -
打印“pdatedAt”作为该列的值。我仍然不知道是什么原因造成的。我的猜测是这与它作为行尾有关,但我不知道为什么它将 u 替换为 '。我想我理解那行在做什么。它转换为 \n,删除每个字段开头和结尾的 ",用 _ 替换空格并删除括号。 csv 中的列名确实包含空格,我使用该命令将它们更改为下划线。我会将 csv 的第一行添加到我的原始帖子中
标签: mysql bash mysqlimport