有没有办法说服 m4 替换单词中间的宏?
我想要这个文件,day.m4:
define(Sat,Cat)dnl
Saturday
和这个命令:
m4 day.m4
产生这个输出:
Caturday
如图所示,m4 不会这样做。
或者,有没有办法让 sed 同时执行多个替换?也就是说,无需为每次替换传递文件。
我可以将一堆 sed 命令连接在一起,或者使用 sed 和 m4 的组合,这还不错,但如果有一种方便的方法可以使用一个输入文件和一个命令来完成此操作,那就更好了。
任何其他常用工具也可以。
我的目标是使用它从模板创建文件。大多数要替换的令牌都是用空格分隔的。
答案1
听起来您所需要的只是:
sed -e sub1 -e sub2 file
其中 sub 具有以下形式:
s/sat/cat/g
您还可以将所有替换放入一个文件中并使用以下命令运行它:
sed -f scriptfile filetomodify
答案2
使用 patsubst()
m4
提供搜索和替换功能,可以在任何地方执行替换,包括词中,称为帕特萨斯特:
内置:patsubst (字符串、正则表达式、[替换])
搜索次数细绳的比赛正则表达式,以及替代品替代品每场比赛。
这不涉及设置新的定义,因此它不能默认应用于所有未来的输入。相反,您必须将完整的输入文本“夹在”函数调用中:
patsubst(dnl
[...]
Saturday
[...]
,`Sat',`Cat')dnl
使用changeword()
m4还提供更改词:
正在处理的文件
m4
被分成带引号的字符串、单词(潜在的宏名称)和简单标记(任何其他单个字符)。最初,单词由以下正则表达式定义:[_a-zA-Z][_a-zA-Z0-9]*
使用
changeword
,您可以更改此正则表达式:
不幸的是,该changeword
功能是非标准的。仅当您--enable-changeword
在编译时请求时它才可用。
启用它后,您可以例如。强制m4
只接受三个字母的单词。
define(`Sat',`Cat')dnl
changeword(`[A-Za-z][a-z]?[a-z]?')dnl
Saturday
但changeword
还有其他问题:
正则表达式必须遵守所需最终模式的每个前缀也被正则表达式接受的约束。
[...]
收紧词法规则不太有用,因为它通常会使某些内置函数不可用。
上面的模式将阻止进一步的定义(它甚至只能识别,dnl
因为这正是三个字母)。因此,它不仅是非标准的,而且并不真正适合您想要做的事情。