shell 如何使用grep删除单词前缀?

enxuqcxy  于 2022-11-16  发布在  Shell
关注(0)|答案(6)|浏览(349)

如何使用grep删除单词的开头?例如,我有一个包含以下内容的文件:

www.abc.com

我只需要这一部分:

abc.com

很抱歉问这个基本的问题,但是我对Linux没有经验。

ljo96ir5

ljo96ir51#

在Unix shell中,你不能用grep来编辑字符串,grep通常用于查找或删除文本中的某些行。你更愿意用sed来代替:

$ echo www.example.com | sed 's/^[^\.]\+\.//'
example.com

您需要学习正则表达式to use it effectively
如果你传递-i参数,Sed也可以就地编辑文件(修改文件),但是要小心,如果你写错了sed命令并使用-i标志,你很容易丢失数据。

示例

从你的评论猜测你有一个TeX文档,并且你想删除所有.com域名的第一部分.如果你的文档是test.tex

\documentclass{article}
\begin{document}
www.example.com
example.com www.another.domain.com
\end{document}

然后,您可以使用以下sed命令转换它(将输出重定向到文件或使用-i就地编辑):

$ sed 's/\([a-z0-9-]\+\.\)\(\([a-z0-9-]\+\.\)\+com\)/\2/gi' test.tex 
\documentclass{article}
\begin{document}
example.com
example.com another.domain.com
\end{document}

请注意:

  • 允许的符号的公共序列后跟一个点,与[a-z0-9-]\+\.匹配
  • 我在正则表达式中使用了组(它在\(\)中的部分)来表示URL的第一部分和第二部分,并将整个匹配替换为它的第二个组(替换模式中的\2
  • 域至少应为第三级.com域(每个\+重复表示至少有一个匹配项)
  • 搜索不区分大小写(最后是i标志)
  • 它可以做的不仅仅是每行匹配(最后是g标志)
gtlvzcf8

gtlvzcf82#

正如其他人所指出的,grep不太适合这个任务,sed是一个很好的选择,或者如果文本有序,简单的cut可能更容易键入:

echo www.abc.com | cut -d. -f2-
  • -d.告诉cut使用.作为分隔符。
  • -f2-告诉cut将字段2返回到无穷大。
3hvapo4f

3hvapo4f3#

您可以使用grep轻松地执行此操作:

$ echo www.google.com | grep -o '[^.]*\.com'
google.com

你必须给予你的文件,而不是echo

$ grep -o '[^.]*\.com$' < file

我在这里使用了正则表达式'[^.]*. com',意思是:找到一个不包含.的单词([^.]*),后面是.com\.com in re)。-o键表示grep必须只显示找到的部分。

5n0oy7gb

5n0oy7gb4#

使用grep的--only-matching\K

您可以使用grep的--only-matching选项来实现这一点:

echo 'www.abc.com' | grep --perl-regexp --only-matching 'www\.\K.*'

其可以被缩短为

echo 'www.abc.com' | grep -Po 'www\.\K.*'

这两个命令都会生成
abc.com
使用grep(GNU grep)3.3.
我将使用here string来代替echo,以进一步缩短命令:

grep -Po 'www\.\K.*' <<< 'www.abc.com'

\K重置匹配的起始点,实际上忽略了匹配的“www."。有关\K的更多信息,请参见this

使用grep的正向后查找

您也可以使用正向后看来执行此操作:

grep -Po '(?<=www\.).*' <<< 'www.abc.com'

带有awk的字段分隔符-F

awk -F 'www\\.' <<< 'www.abc.com' '$2{print $2}'

此打印
abc.com
$2{print $2}部分将打印第二个字段(如果已定义)。这在多行输入的情况下是必要的,以避免在不包含字段分隔符的输入行中输出空行。
正如Vladimir Nesterenco在一个已删除的答案中所指出的,建议在所有这些正则表达式中用反斜杠转义点,以避免匹配以“www”开头的字符串后跟一个 * 任意字符 *,而不仅仅是一个点。否则,您将从“www.example.com“中提取“abc.com“wwwXabc.com。

ubof19bj

ubof19bj5#

grep不用于操作/更改文本,仅用于搜索文本/文本内的模式
如果你想用命令行工具来实现,你应该考虑一下sedawkcut之类的东西,或者用Python/Perl/Ruby或其他什么编写一个脚本。

jgzswidk

jgzswidk6#

实际上,通过使用bash中的内置参数扩展,您可以在不调用其他程序的情况下完成此操作:

while read line; do echo ${line#*.}; done < file

其中#*.告诉shell删除看起来像0个或多个字符后跟.的前缀。
您可以在这里查看bash的不同参数扩展的备忘单:
https://devhints.io/bash

相关问题