我正在尝试每行 grep 一个单词。对于每一行,我想打印 grep 单词之前出现的所有内容。
例子:
echo help.me.nc.example.com is an alias for fd-nc-001.domain.com.
我正在寻找.nc
,我想打印出它之前的所有内容,这将是help.me
.
echo help.me.nc.example.com is an alias for fd-nc-001.domain.com. | awk '{print $6}'
fd-nc-001.domain.com.
echo help.me.nc.example.com is an alias for fd-nc-001.domain.com. | grep .nc | awk '{print $1}'
help.me.nc.example.com
答案1
这会截断字符串第一次出现时的输入行.nc
:
sed 's/\.nc.*//'
(请注意,必须对 in 中的点.nc
进行转义,否则它会匹配任何单个字符。.*
after\.nc
匹配该行的其余部分。)
另外,如果输入行不包含字符串,则不会输出任何内容.nc
(或者更确切地说,它仅在执行替换时输出某些内容,如果该行包含字符串,则会输出内容):
sed -n 's/\.nc.*//p'
该-n
选项可sed
在每个周期结束时禁用缓冲区的默认输出。相反,p
只要触发替换,替换命令中添加的标志就会执行显式输出。
例子:
$ echo help.me.nc.example.com is an alias for fd-nc-001.domain.com. | sed 's/\.nc.*//'
help.me
$ echo help.me.XX.example.com is an alias for fd-nc-001.domain.com. | sed 's/\.nc.*//'
help.me.XX.example.com is an alias for fd-nc-001.domain.com.
$ echo help.me.nc.example.com is an alias for fd-nc-001.domain.com. | sed -n 's/\.nc.*//p'
help.me
$ echo help.me.XX.example.com is an alias for fd-nc-001.domain.com. | sed -n 's/\.nc.*//p'
(最后一个命令没有输出。)
sed -n 's/\.nc.*//p'
执行与仅使用等效的操作awk
:
awk 'sub(/\.nc.*/, "")'
(尝试在每一行上执行替换,但仅在sub()
命令中使用的模式匹配时才打印结果。)
同样的事情,但只使用pcre2grep
:
pcre2grep -o '.*?(*positive_lookahead:\.nc)'
(匹配行的开头和所有内容,但不包括字符串.nc
。)
您可以使用(*pla:
,或更神秘的(?=
, 来代替(*positive_lookahead:
上面的内容。如果您有 GNU grep
,则可以在上一个命令中使用grep -P
来代替。pcre2grep
答案2
.nc
我怀疑您真正想要的是在行后.
或行尾查找,并且您希望在每行上第一次出现该字符(而不是最后一次出现)时进行匹配。这将是其中之一(使用示例输入,测试的不仅仅是.nc
在输入中出现一次而不是作为子字符串的晴天情况):
$ echo 'help.ncc1701.nc.foo.nc.com' | sed -E 's/\.nc(\..*|$)//'
help.ncc1701
$ echo 'help.ncc1701.nc.foo.nc.com' | awk 'sub(/\.nc(\..*|$)/,"")'
help.ncc1701
该 sed 命令需要支持启用 ERE 的 sed -E
,例如 GNU 或 BSD sed,而 awk 命令将在任何 awk 中工作。