首页 > 解决方案 > 使用 Bash 处理字符串时,如何根据逗号是否被某些特定字符包围而区别对待?

问题描述

我想将 MySQL 脚本转换为 JSON 文件,并被要求使用 Bash。通过编写一个简单的 shell 脚本:

#!/bin/bash
# I know this script just output each entry with its value, because I haven' t gone any further
for filename in $dir/home/*.sql
do
    cat $filename | while read line
    do
        names=${line%values*}
        names=${names#*(}
        names=${names%)*}
        values=${line#*values(}
        values=${values%)*}
        while [[ $names != $currentname ]]
        do
            currentname=${names%%,*}
            currentvalue=${values%%,*}
            echo $currentname
            echo $currentvalue
            names=${names#*,}
            values=${values#*,}
        done
    done
done

我已经基本可以满足要求了。然而,还有一个问题。一些字符串条目的字符中有逗号。

这会导致一个错误,即我的脚本将这些逗号视为分隔值的逗号,因此带有逗号的字符串将被视为两个不同的字符串。

使用像 C++ 这样的编程语言来解决这个问题很容易,但是我被要求只使用 bash shell 脚本来解决这个问题,尽管我不熟悉它。所以现在我一直毫无头绪。也许正则表达式可以治愈?或者如果有其他方法也请帮忙。

仅供参考,这是问题的一个示例:

输入:

values(100, 'A100', 'A,100');

预期输出:

100
'A100'
'A,100'

实际电流输出:

100
'A100'
'A
100'

标签: linuxbashshell

解决方案


预期输出:

通常在 shell 中,您会将其与正则表达式匹配:

echo "values(100, 'A100', 'A,100');" | sed 's/values(//; s/\(, \|);\)/\n/g'

但这根本不能解决问题。

最好也是唯一的解决方案是为真正的mysql 语言编写一个真正的解析器来'handle' '' ' ' 'all\tcorner\'cases'正确。逐个字符读取输入字符,存储状态(例如是否在引号内),句柄'\''和其他\n等序列,以满足提取字段的需要。您可能对mysql 内部词法分析器(它很大!)以及 lex 和 yacc 程序感兴趣。

使用http://shellcheck.net检查您的脚本。阅读https://mywiki.wooledge.org/BashFAQ/001。引用变量扩展。不要被无用猫奖提名。

并被要求使用 Bash。

Bash 是一个外壳——它的主要作用是运行和连接其他程序。Bash 是一种外壳,而不是一种成熟的编程语言,在其中编写编程内容将非常困难,或者最终只能使用外部程序,这就是它的用途。用其他语言编写解析器 - 使用 bash 运行它。如果您对 C++ 熟悉,请在 bash 脚本中用 C++ 编写它,然后在 bash 脚本中编译并执行它。


推荐阅读