从文件中search短语后,在行中插入/前缀字符的命令

与我之前在这里发布的问题类似,我正在寻找Linux命令的帮助,执行/执行以下与我原来的问题微妙的不同:

在给定的文件中以大小写不敏感的方式search特定的单词/短语,然后在紧接着的'n'行( 包括该单词的行)插入/前缀字符-- (在这种情况下,这是一个SQL注释) /短语在给定的文件中匹配。

示例:如果我尝试search“CREATE FUNCTION plpgsql_call_handler”这个短语不区分大小写,并且在第102644行匹配,那么我希望在第102644行和紧接着的第2行中插入/前缀字符在给定的文件中。 在这种情况下,我希望插入/前缀行号。 与人物-- 102644,102645,102646。

示例文件:

 102644 CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler 102645 AS '/usr/lib/pgsql/plpgsql.so', 'plpgsql_call_handler' 102646 LANGUAGE c; 

我希望/希望它变成(在这种情况下,这是一个SQL评论):

 102644 -- CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler 102645 -- AS '/usr/lib/pgsql/plpgsql.so', 'plpgsql_call_handler' 102646 -- LANGUAGE c; 

这就是你如何使用sed来完成的:

 sed -r -i -e '/CREATE FUNCTION plpgsql_call_handler/I,+2 s/^/-- /' 

(可能需要GNU sed。)

用你想要的行数replace2(或使用任何其他sed地址forms)。

这比perl怪物简单得多。 而且,perl也可以通过使用-i来实现:

 perl -i -n -e horrible_perl_code /path/to/file 

在这两种情况下,如果您希望保留一个备份更改-i-i.bak

另外,瑞士军团电锯又重新焕发生机:

 perl -n -e 'if (/create/i) { s/^(\d+)/\1 --/; print $_; $_=<> ; s/^(\d+)/\1 --/; print $_; $_=<> ; s/^(\d+)/\1 --/; print $_; } else { print $_; }' < /path/to/file 

它看起来不像可怕! perl -n -e在文件的每一行周围做一个循环,而不是隐式地打印这行,并在每一行上运行提供的perl脚本。

提供的小脚本在每行中查找一个string(这里是create ,但可以随意更改),匹配不区分大小写( /i )。 当它findstring时,它:

  1. 用一行( \1 )加上“ – ”replace一行( ^(\d+) )开头的所有紧接着的数字,
  2. 打印修改后的行
  3. 读取( $_=<> )中的下一行并在该行上重复步骤1和2
  4. 读取下一行并重复该行上的步骤1和2

如果该行不包含该string,则将其未经修改地打印出来。

我相信这可以进一步优化,但希望这将做你想要的。 它发送修改后的文件到STDOUT; 将其捕获到临时文件,并将其移动到原始文件上作为OP的(平凡)练习。

AWK示例:

 awk 'tolower($0) ~ /create function plpgsql_call_handler/ {n=3;} // { if (n-->0) printf "-- "; print $0;}'