使用正则表达式将字段拆分为数组的 Bash 脚本用于多字符分隔符

Posted

技术标签:

【中文标题】使用正则表达式将字段拆分为数组的 Bash 脚本用于多字符分隔符【英文标题】:Bash script to split field into array using regex for multi-character delimiters 【发布时间】:2015-05-20 12:35:26 【问题描述】:

您好——我没有大量的 shell 脚本编写经验,我需要创建一个 bash 脚本来将单个大注释字段拆分为一组单独的注释,使用正则表达式(或多个正则表达式)作为分隔符。我的输入如下所示:

这是第一个音符 (AA 01/23 10:00A)这是第二个音符(AB 01/24 11:00P) 这是第三个音符 (C101/25/201512:15A)这是第四个 (最后)注(D2 03/10 03:15P)

我的数组需要如下所示:

This is the first note          AA  01/23       10:00A
This is the second note         AB  01/24       11:00P
This is the third note          C1  01/25/2015  12:15A
This is the fourth (and final) note D2  03/10       03:15P

详情:

注释可以包含括号,因此我认为我需要使用正则表达式,而不是在每个“)”之后拆分 注释“标签”中的日期(包含在括号中的部分)可以有两种不同的格式 - 有些在日期前后有空格,只有一个 mm/dd 日期,而另一些则将日期显示为 mm/dd/ yyyy 前后没有空格。 注释标签始终以“(AA”) 开头,其中 AA 可以是大写字母和数字字符的任意组合 注释标签始终以“HH:MMA)”结尾,其中 HH 是有效小时,MM 是有效分钟,) 之前的最后一个字符是 A 或 P。

我已经定义了两个正则表达式来识别注释标签的开始和结束,但是我不知道如何将数据实际放入数组中。我的正则表达式是:

starttag= "\([A-Z0-9]2"
endtag= "\d+:\d+[A|P]\)"

我尝试使用 IFS 创建一个数组,但似乎 IFS 不能包含多个字符 - 对吗?我的结果似乎是拆分正则表达式中每个字符的输入,而不是将整个正则表达式评估为单个分隔符。

任何帮助将不胜感激。

【问题讨论】:

你想要一个二维数组吗? Bash 大多只支持一维数组。 不,只是一个一维数组。最终目标是为与订单关联的每个单独的注释创建数据库加载记录。因此,带有 order#/notenotenotenotenote 的传入记录将作为单独的记录 order#/note、order#/note、order# note 写入文件。 我建议您查看 grepawksed 以获取类似的信息。您可以使用 grep 搜索正则表达式并返回它找到的内容。 egrepgrep -egrep -P 应该对您的目标最有用。 “This is the first note”应该是数组元素的索引,而“AA 01/23 10:00A”应该是值吗? 【参考方案1】:

我的 sed 不是最好的,这看起来有点傻而且没有保修:

    eval $(sed 's/\([^()]*\)(\([A-Z0-9]\2\\)\([^AP]*[AP]\)) */\1 \2 \3" "/g ; s/\([^ ]\)\([0-9]\2\:[0-9]\2\[AP]\)/\1 \2/g ; s/ "$//g ; s/^.*/array=("&)/' file)

将“array”更改为您要命名的数组的名称,将“file”更改为文件输入的名称。随着您的测试输入, sed 行扩展为:

array=("This is the first note  AA  01/23 10:00A" "This is the second note AB  01/24 11:00P" "This is the third note  C1 01/25/2015 12:15A" "This is the fourth (and final) note D2  03/10 03:15P")

eval 将其拾取并将其扩展至当前运行的 shell。

【讨论】:

感谢您的建议。我尝试了这个,但我需要评估的传入数据是较大记录中的单个字段,并且似乎 sed 不喜欢这样。这是我尝试过的: 'eval $(sed 's/([^()]*)(([A-Z0-9]\2\)([^AP]*[AP])) */\ 1 \2 \3" "/g ; s/([^ ])([0-9]\2\:[0-9]\2\[AP])/\1 \2/g ; s/ "$//g ; s/^.*/notes=("&)/' 我知道它似乎适用于您的示例数据。很抱歉,它不适用于您的真实数据。

以上是关于使用正则表达式将字段拆分为数组的 Bash 脚本用于多字符分隔符的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式进行数组拆分?

正则表达式将字符串拆分为 char 但具有最大大小

将字符串拆分为字符串数组

使用 SSIS 将单个字段值拆分为第二个表中的多行

使用php preg_match(正则表达式)将camelCase单词拆分为单词

Nifi JSON正则表达式