【问题标题】:grep entire text based on key words根据关键词 grep 整个文本
【发布时间】:2020-08-20 03:30:01
【问题描述】:

我有一个由 oracle select 语句组成的文件,如下所示。

select count(*) into v_cnt from table;
select
  max(num) into v_max 
from table2;
select numm from table3;

输出如下 -

select count(*) into v_cnt from table;
select
  max(num) into v_max 
from table2;

我需要帮助来查找包含在关键字中的选择语句(从选择关键字到分号)。 select 语句可能有 n 行。行首是选择。行尾是分号。如果我们必须在这些关键字之间插入文本。然后我们需要捕获整条线。我正在尝试 grep/awk 语句。但我没有得到exaclty。多行选择语句正在中断。您的任何想法/建议。提前致谢。

【问题讨论】:

  • 如果字符串into 可以出现在输入中的任何其他位置,这样您不希望在出现into 时打印选择语句,那么您应该在示例输入/输出中包含这些情况。

标签: unix awk sed grep


【解决方案1】:

Perl 来救援!

perl -0x3b -ne 'print if /\binto\b/'
  • -0x3b 将记录分隔符设置为字符x3b,即;
  • -n 逐条读取输入记录,为每个记录运行代码
  • \b 匹配单词边界,因此应打印所有包含“into”且不属于较长单词的记录

如果有些命令不是以select 开头并且您想跳过它们,请将条件更改为if /^select\b/m && /\binto\b/(可以合并到单个正则表达式if /^select\b.*\binto\b/ms 中)。要使正则表达式不区分大小写,请添加 /i 修饰符:/^select\b/mi

【讨论】:

    【解决方案2】:

    试试这个:

    tr '\n' '~' < <Input file> | sed 's#;#\n#g' |  grep -i 'select.*into.*' | tr '~' '\n'
    

    演示:

    $cat file.txt 
    select count(*) into v_cnt from table;
    select
      max(num) into v_max 
    from table2;
    select numm from table3;
    $tr '\n' '~' < file.txt | sed 's#;#\n#g' |  grep -i 'select.*into.*' | tr '~' '\n'
    select count(*) into v_cnt from table
    
    select
      max(num) into v_max 
    from table2
    $
    
    

    【讨论】:

      【解决方案3】:

      使用 GNU awk 进行多字符 RS:

      $ awk 'BEGIN{RS=ORS=";\n"} /into/' file
      select count(*) into v_cnt from table;
      select
        max(num) into v_max
      from table2;
      

      使用任何 awk:

      $ awk -v RS=';' -v ORS=';\n' '/into/{sub(/^\n/,""); print}' file
      select count(*) into v_cnt from table;
      select
        max(num) into v_max
      from table2;
      

      【讨论】:

        【解决方案4】:

        awk: issel 记得 select 是否缺少 ;:

        {
                if (issel = (issel || $0 ~ /select/)) print $0;
        
                issel = !( $0 ~ /;/)
        }
        

        【讨论】:

        • $0 ~ /select/ = /select/ and !( $0 ~ /;/) = !/;/ and print $0; = print and {if (issel = (issel || $0 ~ /select/)) print $0;} = @987654@329@ 所以整个 scrtipt 可以减少到 @9867 .
        猜你喜欢
        • 2015-11-29
        • 1970-01-01
        • 2011-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-09
        • 2013-07-11
        • 1970-01-01
        相关资源
        最近更新 更多