将 sed 脚本拉入 perl 程序

2024-01-25

我需要缩短函数名称,因此我识别它们并生成一个非常长的 sed 脚本,如下所示:

s/\breally_long_function_name1\b/A00128/g
s/\breally_long_function_name2\b/A00060/g
s/\breally_long_function_name3\b/A00035/g
s/\breally_long_function_name4\b/A00342/g
s/\breally_long_function_name5\b/A00203/g
...

然后这样称呼它:

`sed -i.bak -f $sedscript *`

问题是我不能依赖sed能够处理这些实例\b而且看起来很乱。我不想写出 sed 脚本,而是想将其放入一个数组中,然后对需要处理的每个文件的每一行执行类似的操作:

$targetline =~ $processing;

我的问题是使用$processing这样是行不通的q运营商似乎不做这项工作。我该如何按摩它才能得到替代品$processing处理并将结果放入$targetline?

注:我用过脚本内的 Perl sed 文件 https://stackoverflow.com/questions/32413831/perl-sed-file-inside-script以及@ron-bergin 的答案,到目前为止。

其应用是将现代 C 代码转换为可以由古代 C 编译器编译的形式。现有脚本位于https://gitlab.com/DavidGriffith/frotz/-/blob/master/src/misc/snavig.pl https://gitlab.com/DavidGriffith/frotz/-/blob/master/src/misc/snavig.pl它用于准备供 KCC 编译的源代码,KCC 是 PDP-10 大型机的早期 C 编译器。它的怪癖之一是某些符号的长度限制为 6 个字符。这方面的背景是https://github.com/PDP-10/panda/blob/master/files/kcc-6/kcc/user.doc#L519 https://github.com/PDP-10/panda/blob/master/files/kcc-6/kcc/user.doc#L519.

这是处理前源文件的片段:

void reset_memory(void)
{
        if (story_fp != NULL)
                fclose(story_fp);
        story_fp = NULL;

        if (undo_diff) {
                free_undo(undo_count);
                zfree(undo_diff);
                zfree(prev_zmp);
        }

        undo_diff = NULL;
        undo_count = 0;
        prev_zmp = NULL;

        if (zmp)
                zfree(zmp);
        zmp = NULL;
} /* reset_memory */

处理后,看起来像这样:

void A00156(void)
{
        if (A00144 != NULL)
                fclose(A00144);
        A00144 = NULL;

        if (undo_diff) {
                A00155(A00148);
                zfree(undo_diff);
                zfree(A00147);
        }

        undo_diff = NULL;
        A00148 = 0;
        A00147 = NULL;

        if (zmp)
                zfree(zmp);
        zmp = NULL;
} /* A00156 */

经过这样的处理后,它被证明可以使用 KCC 进行编译,并在仿真和真实 PDP-10 硬件上的 TOPS20 上运行。

当我尝试不使用外部 sed,而不是做任何事情时,我什么也没得到,然后在按 ^C 时出现大量这样的信息:

Use of uninitialized value $targetline in pattern match (m//) at src/misc/snavig.pl line 181, <$targetfile> line 104.
Use of uninitialized value $targetline in pattern match (m//) at src/misc/snavig.pl line 181, <$targetfile> line 104.
Use of uninitialized value $targetline in pattern match (m//) at src/misc/snavig.pl line 181, <$targetfile> line 104.
Use of uninitialized value $targetline in pattern match (m//) at src/misc/snavig.pl line 181, <$targetfile> line 104.

组织大量替换的一种方法

use warnings;
use strict;
use feature 'say';

my %repl = ( 
    really_long_function_name1 => 'A00128',
    really_long_function_name2 => 'A00060',
    # ...
);

my $re = join '|', keys %repl;  # add quotemeta if needed. see text

while (<>) { 
    s/\b($re)\b/$repl{$1}/g;
    print
}

The <> operator https://perldoc.perl.org/perlop#I/O-Operators reads line by line files with names given on the command line. Each line, changed or not, is merely printed so this acts as a filter. If the files need be edited in place then the code need be adjusted for that.

如果模式中使用的任何键可以具有正则表达式专用的符号,则应该对它们进行转义,并且有一个工具是引用元 https://perldoc.perl.org/functions/quotemeta -- join '|', map { quotemeta } keys %repl。但这里的键是 C 程序中的函数名称。

这并不能解决某些问题(如果某些替换包含在其他替换中怎么办?),并且可能需要根据细节进行其他调整。我不太明白所有要点,特别是为什么将替换列表打印到文件中。如果这很重要,则可以从具有方便格式的文件中读取上面的替换对(Perl 数据结构的转储?JSON? Or YAML这样它也很好读?)

通过向散列添加替换对,可以轻松编辑/扩展该列表。


One way is shown in the SO page linked in the question: set the $^I global variable https://perldoc.perl.org/perlvar#%24%5EI (value of the -i switch). With it being an empty string input files are changed "in-place" but we don't get a backup, otherwise its value is added as a suffix to the backup files

local $^I = '';   # changes made to input files. no backup 

while (<>) { 
    s/\b($re)\b/$repl{$1}/g;
    print;
}

or

local $^I = '.bak';  # added suffix for the backup file(s)

while (<>) { 
    s/.../.../g;
    print;
}

确保此代码的范围足够小,以便能够使用local https://perldoc.perl.org/functions/local限制这种变化——这样解释器的其余部分就不会受到影响!

或者,如果感觉不好,请手动处理文件列表。一旦程序被调用

progname [options]  file1 file2...

然后在运行的程序中数组@ARGV https://perldoc.perl.org/perlvar#@ARGV包含命令行中的所有单词(程序名称除外)。

As @ARGV被处理Getopt::Long破折号选项(带有- or --)被删除,剩下的@ARGV are file1, file2(等)文件名。所以之后Getopt::Long您可以执行的已处理选项

foreach my $filename (@ARGV) { 
    # handle the file $filename
}

或者,从以下位置复制文件名@ARGV从那里到他们自己的数组和进程的安全。 (或者,可以将文件名作为选项的一部分,这样它们将被提取Getopt::Long.)

如果您处理这样的文件(而不是让“钻石”运算符<>这样做)然后还有一些库可以就地更改文件,例如路径::微小::edit_lines https://metacpan.org/pod/Path::Tiny#edit_lines,-edit_lines_utf8,-edit_lines_raw

use Path::Tiny;

path($filename)->edit_lines( sub { s/\b($re)\b/$repl{$1}/g } );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 sed 脚本拉入 perl 程序 的相关文章

  • 调用 Perl 子程序时使用 & 符号和括号

    usr bin perl sub t print in t n print n s sub s print in s n print n t 1 2 print out n print n Output in t 1 2 in s 1 2
  • 如何设置 $!在 Perl 中

    我想在 perl 中编写一些设置 的函数 与内置 perl 函数类似 当我尝试执行此操作时 它抱怨 参数 无法创建管理员用户 在标量分配中不是数字 我试过用谷歌搜索这个 但不幸的是谷歌不会在 所以结果很难得到 if createUser a
  • 如何在 Perl 中以函数式风格进行编码?

    你如何 have a sub返回一个sub or 将文本作为代码执行 in Perl 另外 如何拥有匿名函数存储状态 子返回子作为coderef example 1 return a sub that is defined inline s
  • Perl 中字符串之间的字符匹配计数

    我有一个字符串 例如字符串 1 需要与另一个字符串 字符串 2 匹配 两个字符串的长度相同并且不区分大小写 我想打印两个字符串之间的字符匹配数 E g String 1 stranger String 2 strangem Match co
  • 使用 Perl 分割大文本文件

    我必须将一个 1 8Tb 的大文本文件分成两部分 我只需要文件的后半部分 该文件有 n作为记录分隔符 I tried perl ne print if gt line to start from test txt gt result txt
  • 从日志尾部提取匹配行后退出

    我使用范围运算符来提取日志文件的一部分 例如 tail F logfile perl ne print if b d 现在 一旦提取的部分匹配 我就尝试退出该过程 我尝试过 tail F logfile perl ne print if b
  • Bash - 在 perl 正则表达式中使用变量以及匹配组

    这是我在 stackoverflow 上的第一篇文章 如果我错过了一些重要的内容 请原谅我 我目前遇到以下问题 目标是根据我准备的文件列表动态替换端口号find 这些文件中的所有端口均以数字 4 开头 有 5 位数字 现在是棘手的部分 我只
  • 在 sed 命令和范围地址中使用不同的分隔符

    我在 shell 脚本中使用 sed 来编辑文件系统路径名 假设我想替换 foo bar with baz qux 然而 sed 的s 命令使用正斜杠 作为分隔符 如果我这样做 我会看到发出一条错误消息 例如 sed s foo bar b
  • 为什么使用自动激活文件句柄的三参数开放调用是 Perl 最佳实践?

    我有两个关于 Perl 的问题open功能 1 我好像记得从Perl 最佳实践的 3 参数版本open比两个参数版本更好 例如 open OUT gt gt file vs open OUT gt gt file 这是为什么 前几天我试图告
  • 读入模板文件,使用用户输入填充并生成新文件

    我正在尝试读取如下所示的模板配置文件 template config path to speedseq package binary directory SPEEDSEQ BIN DIR usr local packages Sequenc
  • 无法安装 WWW::Curl::Easy: SZBALINT/WWW-Curl-4.17.tar.gz : make NO

    我正在尝试在我的 Fedora 26 机器上安装 WWW Curl Easy gcc c I usr include D REENTRANT D GNU SOURCE O2 g pipe Wall Werror format securit
  • 在 FOR 循环中打印唯一值

    我有两个文件 myresult 和 annotation 两个文件中的数据似乎是范围 但事实并非如此 这就是为什么我无法将其存储在数组中 我需要使用拆分运算符 以便我可以在 for 循环中使用它并进行比较 现在我需要打印 i myresul
  • 由于 lpcap,CPAN 安装 Net::Pcap 和 Packet 模块失败

    最近 我尝试通过 cpan 安装 perl 模块 Net Packet 和 Net Pcap 但它抱怨找不到 pcap 库 所以我正在搜索 cpan 在安装模块时是否接受外部 lib include 目录 但到目前为止还没有运气 looki
  • 如何编写 Perl 脚本来使用 curl 处理 URL?

    我有一个非常简单的任务 我有一个 crontab 每小时运行一个脚本 该脚本旨在简单地处理 URL 这就是我所拥有的 这不起作用 我收到语法错误 usr bin perl curl http domain com page html 我已经
  • 如何在 sed 中转义方括号[重复]

    这个问题在这里已经有答案了 我正在使用 grep 和 sed 解析遗留的 C 代码 当尝试替换方括号时 发生了一些奇怪的事情 以下代码替换方括号效果很好 echo xyx xzx xyx sed s g 结果是 xyx xzx xyx 当我
  • 如何在 perl 中合并两个数组,交替每个数组中的值

    假设我有 2 个如下所示的数组 a1 Vinay Raj harry b1 dude rock 合并后我想要这样的结果 Vinay dude Vinay rock Raj dude Raj rock harry dude harry roc
  • 向用户提示多个问题(是/否和文件名输入)

    我想问用户多个问题 我有两种类型的问题 是 否或文件名输入 我不知道如何将这一切放入一个好的if结构 我不确定是否也应该使用 else 语句 有人可以帮我们解决这个问题吗 这是我到目前为止所拥有的 print Do you want to
  • 如何将 Perl 转换为 C?

    有没有可用的工具可以将 Perl 源代码转换为 C 源代码 什么平台都可以 对此的规范答案是MJD 的 为什么不将 Perl 翻译成 C http www perl com pub a 2001 06 27 ctoperl html
  • 如何将会话管理添加到简单的 Perl CGI 网页?

    我有一个简单的网页 到目前为止不需要任何登录 它是用 Perl CGI 编程的 我想知道添加会话支持以便获得登录信息的步骤 我不需要非常复杂的方法 因为网页非常简单 另外 我想要一些关于支持 Perl 会话所需的技术 库的建议 我在很多很多
  • 如何在附加的 sqlite 数据库中创建外键?

    我正在尝试创建一个 sqlite3 数据库作为模拟生产环境的测试环境 由于生产的设置方式 表处于多个模式中 我已经在 DBIx Class 中设置了类 使用 schema gt storage gt dbh do将数据库与架构附加在一起 并

随机推荐

  • Cassandra/Spark 显示大表的条目计数不正确

    我正在尝试使用 Spark 处理大型 cassandra 表 约 4 02 亿条目和 84 列 但得到的结果不一致 最初的要求是将一些列从该表复制到另一个表 复制数据后 我注意到新表中的一些条目丢失了 为了验证我是否对大型源表进行了计数 但
  • 安卓框架。它是什么? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 Android 框架有几个问题 有人可以回答吗 他们 Android 框架有什么作用 做 它的工作是什么 这些经理是什么 活动经
  • 在 Perl CGI 中分段 AJAX 响应?

    perl cgi 脚本是否可以将其 AJAX 响应分段为多个单独的 HTTP 响应 假设我有这段代码 xmlhttp new XMLHttpRequest xmlhttp onreadystatechange function if xml
  • 如何通过 StructureMap 映射使用 IRepository 约定

    StructureMap 中是否有一种方法可以用一行或约定进行这种重复映射 For
  • 为什么 Dapper 的 .Execute(...) 返回一个 int ?

    任何人都知道为什么 Dapper 返回一个 int Execute 我在任何地方都找不到这个记录 该整数表示受查询影响的行数 它返回一个整数 以便您知道查询是否有效 如果返回零并且您期望某些内容发生变化 那么您就知道存在问题
  • ReadTheDocs 和 autodoc 在构建期间无法找到我的包

    我一直在尝试在 readthedocs 上为我的第一个 python 包 QutiePy 构建文档 在本地构建文档工作正常 但是当我尝试在 readthedocs 上构建时 autodoc 无法填充我的部分并给出以下警告 WARNING a
  • 创建 Node.js Express 应用程序时出错。找不到

    我正在尝试在 WebStorm 中创建一个 node js 项目 你能告诉我我在这里缺少什么吗 得到了解决方案https intellij support jetbrains com hc en us community posts 115
  • C# 中的转义引号以供 JavaScript 使用

    我有一个 ASP Net Web 处理程序 它以 JSON 格式返回查询结果 public static String dt2JSON DataTable dt String s rows if dt Rows Count gt 0 for
  • matplotlib 的 plt.acorr 中自相关图的错误?

    我正在用 python 绘制自相关 我使用了三种方法来做到这一点 1 pandas 2 matplotlib 3 statsmodels 我发现我从 matplotlib 得到的图与其他两个不一致 代码是 from statsmodels
  • 记录到文件还是数据库更好?

    我们仍在使用旧的经典 ASP 并且希望在用户在我们的应用程序中执行某些操作时进行记录 我们将编写一个通用子例程来获取我们想要记录的详细信息 我们是否应该使用以下命令将其记录到 txt 文件中FileSystemObject或者将其记录到 M
  • 如何继承多模块 Maven 项目及其所有优点?

    我找不到一个好的 可扩展的解决方案的问题 我有一个项目可以提供给定工件的多种风格 这是一个多模块项目 目前有 3 个模块 flavor1 模块 flavor2 模块 flavor3 模块 问题是我还有另外 50 个项目需要以相同的方式设置
  • 停止闹钟 Android 应用程序

    谁能告诉我怎样才能停止这个警报 我试图通过使用处理程序来阻止它 但它并没有阻止它继续重复 这是我的代码 更新后 Button bStart bStop long mCurrentTime Calendar calendar TextView
  • 什么库/如何在 Windows32 上用 C 播放 wav 文件?

    在 Win32 系统上播放 wav 文件需要哪些 C 语言库 使用这些库的代码是什么 使用 Win32 API 播放声音 http msdn microsoft com en us library dd743680 v VS 85 aspx
  • SpriteKit 自动恢复和自动暂停 iOS8

    场景在 applicationWillResignActive 时自动暂停 并在 applicationDidBecomeActive 运行时自动取消暂停 我希望通过 nsnotification 在 applicationWillResi
  • 如何使用 Java 配置在 Tomcat 8 中配置 JNDI 数据源:

    如何在 Java 配置文件中配置 JNDI 数据源 而不是遵循 web xml Servlet 上下文中的代码片段
  • matplotlib 绘图不出现

    我正在使用 python v3 6 与 pycharm 和 anaconda 我尝试运行下面的代码来绘制一个简单的正弦波 import numpy as np import matplotlib pyplot as plt Generate
  • Android Studio 无法将 Nexus 7 识别为设备

    我在 Nexus 7 上运行我在 Android Studio 中开发的应用程序时遇到问题 在使用同一台平板电脑和计算机 运行 Windows 8 之前 我已成功使其正常工作 但自从我的笔记本电脑修好并且所有内容都被擦除后 我确信我的开发环
  • 给定文件类型的持久 :set 语法?

    我正在开发一个使用 Twig 的 Symfony 项目 文件类型是myfile html twig Vim 不会自动检测语法突出显示 因此不应用任何语法 我可以用 set syntax HTML打开文件后 但在文件之间跳转时很痛苦 有没有办
  • PHP/pthreads Thread 类不能使用数组?

    我找到了一个 PECL pthreadThread不能使用数组对象 我该怎么做才能找到原因 代码示例 class my extends Thread public function construct this gt arr array t
  • 将 sed 脚本拉入 perl 程序

    我需要缩短函数名称 因此我识别它们并生成一个非常长的 sed 脚本 如下所示 s breally long function name1 b A00128 g s breally long function name2 b A00060 g