繁体   English   中英

查找在其他行上的其他两个字符串之间的所有字符串实例

[英]Find all instances of string between two other strings that are on other lines

所以我觉得我应该知道该怎么做,但我做不到。

我正在尝试查找所有实例(在所有文件中),其中两个字符串之间(通常在其他行上)@GROUP和@END_GROUP中存在以_START结尾的字符串

所以可能会有这样的代码

// @GROUP GroupName OtherStuff
#define GROUPNAME_START 1
#define GROUPNAME_FOO 2
.... (more defines)
#define GROUPNAME_END 10
// @END_GROUP

#define GROUPTWO_START 1
// @GROUP GroupTwo MoreStuff
#define GROUPTWO_FOO 2
.... (some defines)
#define GROUPTWO_BAR 70
// @END_GROUP

我想匹配第一个组(实际上只匹配_START行,但一切正常),但不匹配第二个组或@GROUP注释之外的_START行。

我认为为此使用grep将是搜索所有文件的最佳方法,但是我不能完全获得所需的正则表达式。 谢谢您的帮助。

编辑:我的缺点是无法明确表示我希望能够同时搜索多个目录中的文件,就像grep -r“ foo” *一样。 答案很好,我只是没有说清楚。

edit2:多个很好的答案每个都以略有不同的方式解决了它,我真的不知道哪个是最好的。 我标记了第一个回答的人,但是任何关注此问题的人都应该确保检查出所有答案,一个可能会更好地解决您的问题。

grep只看到一行,因此它不知道它是否在组注释之间。 sed可以使用地址,但是:

sed '/@GROUP/,/@END_GROUP/!d' input_file | grep '_START'

! 取反地址, d删除一行,即我们告诉sed删除不在组注释之间的行。 然后grep仅在“有趣”行上运行。

要使其也适用于子目录,请在工具箱中添加find

find /path/to/dir -type f -exec sed '/@GROUP/,/@END_GROUP/!d' {} + | grep '_START'

或者,如果组注释可能没有相应的END出现,请使用较慢但更安全的方法

find /path/to/dir -type f -exec sed '/@GROUP/,/@END_GROUP/!d' {} \; | grep '_START'

或者,让xargsgrep -l的输出进行操作:

grep -lr @GROUP /path/to/dir | xargs sed '/@GROUP/,/@END_GROUP/!d' | grep '_START'

注意:如果文件名包含空格,则无法使用。

使用awk您可以使用空RS并在单个搜索中完成所有操作:

awk -v RS= '/@GROUP.*_START.*@END_GROUP/' file
// @GROUP GroupName OtherStuff
#define GROUPNAME_START 1
#define GROUPNAME_FOO 2
.... (more defines)
#define GROUPNAME_END 10
// @END_GROUP

这是sed的工作,使用其地址语法:

#!/bin/sed -f

/@GROUP/h  # store the @GROUP line

/@GROUP/,/@END_GROUP/{
/_START/{
g  # retrieve the @GROUP line
n  # print it and continue
}
}

# otherwise, delete the line and continue
d

嵌套的块有点复杂,但是它的作用是:在@GROUP .. @END_GROUP ,然后对于匹配_START任何行,它将打印先前找到的@GROUP行(因此,使用您的示例):

$ ./group.sed group.data 
// @GROUP GroupName OtherStuff

这就是您要达到的目标吗?

编辑 :这不是您要的-您只需要_START行,而不是@GROUP行。 嗯,这要容易得多:

#!/bin/sed -nf
/@GROUP/,/@END_GROUP/{
/_START/p
}

附录 :由于您现在要求递归目录搜索,因此可以按照其他答案中的描述使用find

find . -type f -print0 | xargs -0 ./group.sed --separate

(我在这里使用了GNU sed --separate参数来防止任何文件以组开头但缺少组结束行)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM