如何使用sed/grep提取两个单词之间的文本?

18 浏览
0 Comments

如何使用sed/grep提取两个单词之间的文本?

我正在尝试输出一个包含字符串两个单词之间所有内容的字符串:\n输入:\n\"Here is a String\"\n输出:\n\"is a\"\n使用:\nsed -n \'/Here/,/String/p\'\n包括了起点和终点,但我不想包括它们。

0
0 Comments

如何使用sed/grep提取两个单词之间的文本?

这个问题的原因是,接受的答案没有删除Here之前或String之后的文本。以下解决方法可以解决这个问题:

sed -e 's/.*Here\(.*\)String.*/\1/'

主要区别是在Here之前和String之后添加了.*

你的答案很有希望。不过有一个问题,如果同一行中有多个String,我该如何提取到第一个出现的String?谢谢。

你需要将*量词设置为非贪婪模式(lazy),即在HereString之间。然而,sed使用的正则表达式类型不支持懒惰量词(?紧跟在.*之后),根据这个Stackoverflow问题。通常,要实现懒惰量词,你只需要匹配除了你不想匹配的标记之外的所有内容,但在这种情况下,不仅仅是一个单个标记,而是一个完整的字符串String

谢谢,我使用awk得到了答案,stackoverflow.com/questions/51041463/…

不幸的是,如果字符串中有换行符,这个方法不起作用。

这是正常的。点.不匹配换行符。如果你想匹配换行符,你可以将.替换为例如[\s\s]

.替换为[\s\s]不会删除换行符。

糟糕,应该是[\s\S]

0
0 Comments

sed和grep是在Unix/Linux系统中常用的文本处理工具。有时候我们需要从一段文本中提取出某两个关键词之间的内容,这时就可以使用sed或者grep来完成。

在这个问题中,用户想要从字符串"Here is a one is a String"中提取出"one is"和"String"之间的内容。最初的解决方法是使用sed命令:sed -e 's/one is\(.*\)String/\1/'。然而,这个命令会同时提取出"Here is a",而不仅仅是"one is"和"String"之间的内容。

为了只提取出"one is"和"String"之间的内容,用户需要修改正则表达式,使其匹配整行文本。修正后的命令是:sed -e 's/.*one is\(.*\)String.*/\1/'。在sed中,s/pattern/replacement/的意思是"在每一行上将'pattern'替换为'replacement'"。只有匹配到"pattern"的部分才会被替换,所以如果想要替换整行文本,就需要让"pattern"匹配整行。

然而,这个解决方法在输入为"Here is a String Here is a String"的情况下会出现问题。为了解决这个问题,用户提出了一个新的需求:只提取出第一个"Here"和"String"之间的内容。正则表达式不支持非贪婪匹配,所以无法直接实现这个需求。用户在问题中提供了一个链接,其中有一些推荐的替代方案。

用户在这个问题中遇到了提取两个关键词之间内容的需求,最初使用的命令无法完全满足需求,后来通过修改正则表达式实现了只提取关键词之间内容的目标。然而,在处理特定的输入情况时,用户发现了解决方案的局限性,需要寻找替代方案来满足新的需求。

0
0 Comments

如何使用sed/grep提取两个单词之间的文本?

问题的原因是,有时我们需要从文本中提取两个特定单词之间的内容。在这种情况下,我们可以使用sed或grep命令来实现。下面是解决此问题的方法:

对于grep命令,可以使用正向和负向前瞻和后顾来提取文本。对于这个问题,命令如下:

echo "Here is a string" | grep -o -P '(?<=Here).*(?=string)'

如果存在多个“Here”和“string”的出现,您可以选择是否要从第一个“Here”和最后一个“string”进行匹配,或者单独匹配它们。在正则表达式中,这被称为贪婪匹配(第一种情况)或非贪婪匹配(第二种情况)。

$ echo 'Here is a string, and Here is another string.' | grep -oP '(?<=Here).*(?=string)' # 贪婪匹配
 is a string, and Here is another 
$ echo 'Here is a string, and Here is another string.' | grep -oP '(?<=Here).*?(?=string)' # 非贪婪匹配
 is a 
 is another 

请注意,GNU grep的-P选项在包括*BSD在内的grep中不存在,或者在任何SVR4(Solaris等)中提供的grep中也不存在。在FreeBSD中,您可以安装包含pcregrep的devel/pcre端口,该端口支持PCRE(以及前瞻/后顾)。OSX的旧版本使用GNU grep,但在OSX Mavericks中,-P派生自FreeBSD的版本,不包括该选项。

如果您的结束字符串“string”出现多次,上述方法将获取最后一次出现的内容,而不是下一次出现的内容。

对于这种情况,您可以使用以下命令:

echo "Here is a string a string" | grep -o -P '(?<=Here).*?(?=string)'

请注意,grep的-P标志在MacOS X 10.9及以上版本中不起作用。但您可以按照这个指南将其转换为perl命令。

对于处理XML文件,应避免使用文本操作命令(如awk、sed)进行解析。而应该使用xmlstarlet。不过,您仍然可以像处理其他文本文件一样使用sed/awk处理XML。

如果要在结果中包含“Here”和“string”,可以使用以下命令:

grep -o 'Here.*string' 或者 grep -oP 'Here.*?string'

如果两个模式位于不同的行上,您需要启用pcregrep的多行搜索功能。可以使用以下命令:

echo $'Here is \na string' | grep -zoP '(?<=Here)(?s).*(?=string)'

如果只想在第一个匹配处停止,可以使用一些简单的技巧。将输入和搜索字符串颠倒,执行非贪婪搜索并颠倒结果。可以使用rev命令来实现。

如果希望从最后一个“Here”和“string”之间捕获文本,可以使用sed或perl命令:

perl -nE 'say /.*(?<=Here)(.*)String/' 或 sed -r 's/.*Here(.*)String/\1/'

以上就是使用sed/grep提取两个单词之间文本的方法。

0