我将尝试输出一个包含字符串中两个单词之间所有内容的字符串:
输入:
输入:
"Here is a String"
输出:
"is a"
使用:
sed -n '/Here/,/String/p'
这个包含了端点,但我不想把它们包含在内。
GNU 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)' # Greedy match
is a string, and Here is another
$ echo 'Here is a string, and Here is another string.' | grep -oP '(?<=Here).*?(?=string)' # Non-greedy match (Notice the '?' after '*' in .*)
is a
is another
-P
选项在*BSD中包含的grep或任何SVR4(Solaris等)附带的grep中都不存在。在FreeBSD中,您可以安装devel/pcre
软件包,其中包括支持PCRE(和前后查找)的pcregrep
。较旧版本的OSX使用GNU grep,但在OSX Mavericks中,-P
源自FreeBSD的版本,该版本不包括该选项。 - ghoti" is a "
和" is a string a "
两个答案都是符合问题要求的有效回答(忽略引号)。根据您的要求,可以根据您的喜好选择其中一个进行回答。无论如何,以下命令可满足您的需求:echo "Here is a string a string" | grep -o -P '(?<=Here).*?(?=string)'
。 - anishsaneecho $'Here is \na string' | grep -zoP '(?<=Here)(?s).*(?=string)'
- anishsanesed -e 's/Here\(.*\)String/\1/'
echo "Here is a one is a String" | sed -e 's/one is\(.*\)String/\1/'
。如果您只想得到"one is"和"String"之间的部分,则需要让正则表达式匹配整行内容:sed -e 's/.*one is\(.*\)String.*/\1/'
。在sed中,s/pattern/replacement/
表示“将每一行上与‘pattern’相匹配的内容替换为‘replacement’”。它只会改变与“pattern”相匹配的内容,因此如果您想要替换整行内容,必须让“pattern”匹配整行内容。 - Brian CampbellHere is a String Here is a String
时,这会出现错误。 - Jay D被接受的答案没有删除可能在Here
之前或String
之后的文本。这样做会:
sed -e 's/.*Here\(.*\)String.*/\1/'
主要区别在于在String
之后和Here
之前立即添加.*
。Here
和 String
之间的 *
量词设置为非贪婪模式(或懒惰模式)。然而,sed 使用的正则表达式类型不支持懒惰量词(即在 .*
后面紧跟着一个 ?
)根据 这个 Stackoverflow 问题。通常,要实现懒惰量词,您只需匹配除了您不想匹配的标记之外的所有内容,但在这种情况下,不仅仅是单个标记,而是整个字符串 String
。 - wheeler如果您有一个包含很多多行出现的长文件,最好先打印行号:
cat -n file | sed -n '/Here/,/String/p'
cat
中的-n
选项。 - Jeffrey Lebowskicat
可以完全省略;sed
知道如何读取文件或标准输入。 - tripleee通过 GNU awk,
$ echo "Here is a string" | awk -v FS="(Here|string)" '{print $2}'
is a
使用-P
(Perl正则表达式)参数的grep支持\K
,它有助于丢弃先前匹配的字符。在我们的情况下,先前匹配的字符串是Here
,因此它被从最终输出中丢弃。
$ echo "Here is a string" | grep -oP 'Here\K.*(?=string)'
is a
$ echo "Here is a string" | grep -oP 'Here\K(?:(?!string).)*'
is a
如果您希望输出为is a
,那么您可以尝试以下方法:
$ echo "Here is a string" | grep -oP 'Here\s*\K.*(?=\s+string)'
is a
$ echo "Here is a string" | grep -oP 'Here\s*\K(?:(?!\s+string).)*'
is a
echo "Here is a string dfdsf Here is a string" | awk -v FS="(Here|string)" '{print $2}'
,它只会返回 is a
而不是应该返回的 is a is a
。@Avinash Raj - alpersed
命令,我们需要逐步构建它。以下是原始文本:user@linux:~$ echo "Here is a String"
Here is a String
user@linux:~$
让我们尝试使用sed
中的替换选项s
来删除字符串Here
user@linux:~$ echo "Here is a String" | sed 's/Here //'
is a String
user@linux:~$
此时,我相信您已经能够移除String
了。
user@linux:~$ echo "Here is a String" | sed 's/String//'
Here is a
user@linux:~$
但这不是您想要的输出。
要结合两个sed命令,请使用-e
选项。
user@linux:~$ echo "Here is a String" | sed -e 's/Here //' -e 's/String//'
is a
user@linux:~$
$ echo "Here is a String" | sed 's/.*Here//; s/String.*//'
is a
同样适用
$ echo "Here is a StringHere is a String" | sed 's/.*Here//; s/String.*//'
is a
$ echo "Here is a StringHere is a StringHere is a StringHere is a String" | sed 's/.*Here//; s/String.*//'
is a
sed '/Here/!d;s//&\n/;s/.*\n//;:a;/String/bb;$!{n;ba};:b;s//\n&/;P;D' file
Here
和String
)显示在新行上,并保留文本中的换行符。以上所有解决方案都存在缺陷,即最后一个搜索字符串在字符串的其他位置重复出现。我发现编写一个bash函数是最好的选择。
function str_str {
local str
str="${1#*${2}}"
str="${str%%$3*}"
echo -n "$str"
}
# test it ...
mystr="this is a string"
str_str "$mystr" "this " " string"
Here is a Here String
,结果应该是什么?或者是I Hereby Dub Thee Sir Stringy
? - ghoti