正则表达式不适用于sed

时间:2013-11-13 23:27:42

标签: regex bash sed

很抱歉,如果标题不够具有描述性,但我真的不知道如何总结它,欢迎提出任何建议。我写了一个有用的正则表达式来匹配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无法实现什么是好的选择呢?是什么类似的东西会这样做?

4 个答案:

答案 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:

而不是sed
perl -e 'undef $/; $_ = <>; s/YOUR_REGEX_HERE//gs; print' $1

答案 3 :(得分:0)

通过将所有内容保存在缓冲区来启动你的sed

sed "H
$ {
  x
#  your code here
  }
  1. H将每一行加载到缓冲区
  2. 当最后一行($)出现时
  3. 与缓冲区交换当前行(因此所有文件都在您的工作区中)
  4. 您的代码可以在所有行上运行。
  5. 是careefful,^和$是文件的第一个和最后一个字符,不再是由\ n

    分隔的行