很抱歉,如果标题不够具有描述性,但我真的不知道如何总结它,欢迎提出任何建议。我写了一个有用的正则表达式来匹配sql文件中的行,即将数据插入特定的表(包含缓存)。它是这样的:
(--\s--\sDumping\sdata\sfor\stable\s`(cache_\w+|cache)`.*?)(?=(--\n--.+Table\sstructure\sfor\stable\s`.+`.*--))
所以现在当我有这样的文件:
--
-- Table structure for table `cache_content`
--
something
--
-- Dumping data for table `cache_content`
--
INSERT INTO `cache_content` etc.
--
-- Table structure for table `cache`
--
something
--
-- Dumping data for table `cache`
--
INSERT INTO `cache` etc.
--
-- Table structure for table `notcache`
--
something
--
-- Dumping data for table `notcache`
--
它匹配那些表的所有插入,我想通过使用sed
删除它们(因为那些是带缓存的表),特别是我写了一个简单的bash脚本来执行此操作:
REGEX="(--\s--\sDumping\sdata\sfor\stable\s\`(cache_\w+|cache)\`.*?)(?=(--\n--.+Table\sstructure\sfor\stable\s\`.+\`.*--))"
sed -i "s/${REGEX}//g" $1
现在问题是它在我的正则表达式测试器中有效,但它对sed
完全不起作用。 sed
根本就没有更改文件,我已经被缓和了。我在某处读到sed
是基于行的,但这可能是问题,还是其他什么?
添加#1:
如果用sed
无法实现什么是好的选择呢?是什么类似的东西会这样做?
答案 0 :(得分:2)
不,你不能使用sed
,因为它是面向行的,你的模式必须匹配多行。 (您可以将模式分解为开始模式和结束模式并尝试/start_pattern/,/end_pattern/p
,但是您需要为每个表单独start_pattern
个,因为{{1}中的行范围只能在输入中匹配一次。)
您应该能够在sed
中采用简化的开始模式/结束模式方法:
awk
或者您仍然可以使用“真正的”脚本语言对整个文件进行一次巨大的regexp(稍作修改):
awk 'BEGIN { x = 1 }; /^-- Dumping data for table `cache(_[a-zA-Z0-9]+)?`$/ { x = 0 }; /^-- Table structure for table `[^`]+`$/{ x = 1 }; (x == 1) { print }' $1
答案 1 :(得分:1)
为什么要创建额外的工作,如果你可以首先避免它? :)
根本不为您不感兴趣的表生成语句。例如,如果您使用的是MySQL:
mysqldump --ignore-table=<...> --ignore-table=<...>
其他数据库也有类似的选择。
答案 2 :(得分:0)
尝试使用perl:
而不是sedperl -e 'undef $/; $_ = <>; s/YOUR_REGEX_HERE//gs; print' $1
答案 3 :(得分:0)
通过将所有内容保存在缓冲区来启动你的sed
sed "H
$ {
x
# your code here
}
是careefful,^和$是文件的第一个和最后一个字符,不再是由\ n
分隔的行