我一直在尝试在 bash 中进行字符串替换类型的操作。但这并不像看起来那么容易,因此解释如下:
假设您有一个 SQL 文件,其中包含多个选择其中的陈述。每个选择块以分号结束(;)。
我的目标是单独抓取每个块并用它执行一些操作。但是,脚本应该能够动态识别这些块,因为它将使用不同的 sql 文件并将每个块存储到变量中(例如1 美元),以便以后可以轻松使用该块。
PS 过去一周我一直在解决这个问题,任何建议将不胜感激。此外,您还可以在下面看到我迄今为止使用过的一些正则表达式类型的东西:
egrep -e "^(\s|SELECT).*.[^;]\s*" test.sql
和这个
cat test.sql | awk '" "{found=0} /SELECT/{found=1} {if (found) print }'
第一个效果最好,最接近目标,但我找不到分离和存储 SELECT 语句块的方法。第二个使用类似的表达式来查找分号。除此之外,我尝试告诉脚本使用它们之间的任何内容作为第三个项目,然后尝试将这三个项目作为一个整体存储在一起。但无法使其发挥作用。 SELECT 语句是多行的。
答案1
您可以使用带有“换行符”以外的分隔符的读取循环。这将导致read
命令bash
将多行视为一行,前提是它们以分隔符结尾。
注意:如果分号可能出现在文件中的注释或字符串中,则此方法不适合。这不是一个解析器 - 只是一个简单的读取循环。
while read -rd ';' sql
do
if [ "${sql#SELECT}" = "$sql" ]
then
echo "Not a SELECT!"
else
echo "This is the command I got:"
echo ">>$sql<<"
fi
done < test.txt
将read -rd ';' sql
读取输入直到看到分号。该块将位于变量 中$sql
。
if
循环内部检查从变量中的文本开头删除单词是否会SELECT
更改它 - 它基本上是询问文本是否不以单词 开头SELECT
。
请注意,read
在查找“单词”时,将删除每个块中的首字母和尾随空格。因此,分号前后的空行将被删除。
文本文件示例:
SELECT *
FROM PLANTS
WHERE TYPE='BUSH'
;
INSERT INTO PLANTS (TYPE,NAME,ID)
VALUES ('TREE', 'Oak', 15) ;
SELECT NAME
FROM PLANTS
WHERE NAME LIKE 'O%';
将产生以下输出:
This is the command I got:
>>SELECT *
FROM PLANTS
WHERE TYPE='BUSH'<<
Not a SELECT!
This is the command I got:
>>SELECT NAME
FROM PLANTS
WHERE NAME LIKE 'O%'<<
答案2
awk -v RS=";" '/SELECT/{print $0";"}'
如果一条记录(其中RS
is ;
)有字符串,它将在末尾SELECT
一起打印。;