如何提取分隔符前后的字符串并存储在mysql中?

How to extract strings before and after a delimiter and store in mysql?

想要在一个包含两列的 mysql table 中插入一个 txt 文件,其中包含大量包含以下结构的行:

random1:random2:random3:random4
random1:random2:random3:random4:random5
random1:random2
random1:random2:random3:random4:randomN
...

其中分隔符为":"

而"random"代表一组随机字符。

第一列应该是字符串 random1

第二列应该存储字符串的其余部分random2:random3:random4:randomN

要提取第一列的子字符串,已经尝试过:

echo "random1:random2:random3:random4:randomN" | awk -F":" '{print (NF>1)?  : ""}'

echo "random1:random2:random3:random4:randomN" | sed 's/:.*//'

echo "random1:random2:random3:random4:randomN" | cut -d ":" -f1

如何从第一个分隔符“:”提取子字符串直到行尾并将其存储在mysql table?

提前致谢!

在 MySQL 中,您可以按照以下步骤使用 : 分隔符拆分字符串:

SELECT 
    SUBSTRING_INDEX(SUBSTRING_INDEX(mycolumn, ':', 1), ':', -1) as random1,
    SUBSTRING_INDEX(SUBSTRING_INDEX(mycolumn, ':', 2), ':', -1) as random1,
    ...
    SUBSTRING_INDEX(SUBSTRING_INDEX(mycolumn, ':', N), ':', -1) as random1,
FROM myTable;

请注意,此技术要求您提前知道字符串中的最大部分数。

这是您的部分解决方案(可能):

while IFS=: read -r first rest; do
    do_something_with "$first" "$rest"
done < colon-separated-file.txt

这会将第一个“:”更改为“,”以生成 CSV 文件:

sed -E "s/([^:]*):/,/" myfile.txt > myfile.csv

然后您可以将其导入您的 table。

或者,您可以创建一个 SQL 脚本:

sed -E "s/([^:]*):(.*)/insert into mytable (col1, col2) values ('','');/" myfile.txt > myfile.sql

然后运行它:

mysql -u root mydatabase -s < myfile.sql

如果我们要调用 MySQL 将大量行插入 table... 假设 random1、random2、random3 的 "random" 性质不包括文字制表符0x09'\t'...

我不会在 bash 中解析文件,那是很多开销。我只是执行 mysql 客户端,并发出 MySQL LOAD DATA 语句,让 MySQL 读取文件并解析它。

例如

假设我们要向 mytablecol1col2 中插入行,如下所示:

LOAD DATA LOCAL INFILE '/tmp/foo.txt'
INTO mytable 
( @foo
)
SET col1 = SUBSTRING_INDEX(@foo,':',1)
  , col2 = IF(LOCATE(':',@foo)>0,SUBSTRING(@foo,LOCATE(':',@foo)+1,10000),'')

参考:https://dev.mysql.com/doc/refman/8.0/en/load-data.html


作为 LOAD DATA 语句中使用的表达式的演示:

SELECT t.foo
     , SUBSTRING_INDEX(t.foo,':',1) AS foo1
     , IF(LOCATE(':',t.foo)>0,SUBSTRING(t.foo,LOCATE(':',t.foo)+1,10000),'') AS foo2
 FROM ( SELECT 'a' AS foo 
        UNION ALL SELECT ':b'
        UNION ALL SELECT '::c'
        UNION ALL SELECT ':::d'
        UNION ALL SELECT 'a:b'
        UNION ALL SELECT 'a:::d'        
        UNION ALL SELECT 'a:b:c'        
        UNION ALL SELECT 'a:b:c::e'
      )  t

returns

foo       foo1  foo2
--------  ----  -------
a         a     
:b              b
::c             :c
:::d            ::d
a:b       a     b
a:::d     a     ::d
a:b:c     a     b:c
a:b:c::e  a     b:c::e

你也可以试试 Perl

$ cat carlos.txt
random1:random2:random3:random4
random1:random2:random3:random4:random5
random1:random2
random1:random2:random3:random4:randomN
$ perl -F: -lane ' print "insert into mytable (col1, col2) values (\x27",$F[0],"\x27,\x27",join(":",@F[1..$#F]),"\x27);" ' carlos.txt
insert into mytable (col1, col2) values ('random1','random2:random3:random4');
insert into mytable (col1, col2) values ('random1','random2:random3:random4:random5');
insert into mytable (col1, col2) values ('random1','random2');
insert into mytable (col1, col2) values ('random1','random2:random3:random4:randomN');
$