3

我有许多 M4 宏文件,我希望从中提取文件路径的单个实例(如果存在)。

在每个文件中都有一行

define(`XSETROOT', `some_command with parameters SOME_DIR/subdir1/subdir2/filename')

或分布在两条线上

define(`XSETROOT', dnl
`some_command with parameters SOME_DIR/subdir1/subdir2/filename')

或根本没有条目。

所以我希望找到开始的行

define(\`XSETROOT',

然后从同一行或下一行提取以“空格”和“单引号”为界的字符串,即

SOME_DIR/subdir/subdir/filename

这可以在不诉诸多个 sed 调用的情况下完成吗?

附加信息(下面评论字段中的格式似乎不起作用)-

在最简单的情况下,当一切都在同一行时,引号的问题可以通过适当的引用/取消引用来克服,并且这个表达式有效

sed -ne 's|define(`XSETROOT'\'',.*`.* \(.*\)'\''.*|\1|p' file.m4

更多信息 -

感谢 MvG 的响应展示了如何进行多行处理,当数据分成两行时,这个表达式有效

sed -ne '/define(`XSETROOT/{n;s|`.* \([^'\'']*\)'\'').*|\1|p}' file.m4

但是问题仍然存在,是否有可能构造一个表达式来处理一两行上的数据,或者我是否必须尝试一个来查看是否有返回的字符串,如果没有,则尝试另一个来查看如果返回一个字符串?

4

3 回答 3

0

如果您可以使用awk它可能对您有用:

awk -F "[`']" 'BEGIN { RS=")" } { print gensub(".* ","","g",$4) }' INPUTFILE

请参阅此处的实际操作(几乎与 Ideone.com 不支持 CLI 参数相同)。

解释:

  1. -F "[`']"将字段分隔符设置为[`'](这两个引号字符中的任何一个)的正则表达式
  2. RS=")"设置记录分隔符,这样我们就可以拥有多行记录
  3. gensub(".* ","","g",$4)返回第四个字段中最后一个空格后的所有内容
于 2012-09-04T21:09:33.227 回答
0

尝试这个:

sed -n "/define(\`XSETROOT'/{/dnl/N;s/.* //;s/'.*//;p}"
  • 除非当前行包含define(`XSETROOT'.
  • 如果该行还包含dnl,则追加下一行。
  • 删除直到最后一个空格的所有内容。
  • 删除最后一个单引号后的所有内容。
  • 打印剩余的字符串。

N命令限制为实际存在 a 的情况有dnl两个目的:它允许在文件末尾匹配单行定义,并且它允许两个后续定义,其中第一个仅占一行。

于 2012-09-04T21:11:31.180 回答
0

正确的解决方案是使用 M4 本身。

m4 -D XSETROOT='some suitable value with a/path/to/a/file' file.m4
于 2016-07-25T11:20:21.273 回答