从文件中搜索短语后在行中插入/添加前缀字符的命令

从文件中搜索短语后在行中插入/添加前缀字符的命令

与我发布的问题类似这里之前,我正在寻找一个 Linux 命令帮助,它执行以下操作,与我最初的问题有细微的差别:

--在给定文件中不区分大小写地搜索特定的单词或短语,然后在紧接着的“n”行中插入或添加字符(在本例中为 SQL 注释)作为前缀包括给定文件中匹配单词或短语的行。

例子: 如果我尝试不区分大小写地搜索短语“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;

答案1

您可以这样使用 sed 来执行此操作:

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

(可能需要 GNU sed。)

将 2 替换为您想要的行数(或使用任何其他 sed 地址形式)。

这比那个 perl 怪物要简单得多。此外,perl 也可以通过使用以下方法就地完成此操作-i

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

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

答案2

再一次,老式的瑞士军用电锯开始运转:

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 脚本。

提供的小脚本在每一行中查找一个字符串(这里是create,但您可以根据需要更改它),不区分大小写地匹配(/i)。当它找到字符串时,它会:

  1. 将行首所有直接连续的数字 ( ^(\d+)) 替换为其自身 ( \1) 加“--”,
  2. 打印修改后的行
  3. 读入 ( ) 中的下一行$_=<>并对该行重复步骤 1 和 2
  4. 读入下一行并对该行重复步骤 1 和 2

如果该行不包含该字符串,则不加修改地打印它。

我确信这可以进一步优化,但希望它能满足您的要求。它将修改后的文件发送到 STDOUT;将其捕获到临时文件并将其移动到原始文件上,这留给 OP 做(微不足道的)练习!

答案3

AWK 示例:

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

相关内容