使用 awk 或 sed 删除子域

使用 awk 或 sed 删除子域

如何删除文本文件中的所有子域?我想我需要删除之前的所有内容,包括“.”?

输入:

unix.stackexchange.com
www.example.org
example.example.tld

预期输出:

stackexchange.com
example.org
example.tld

编辑:

没有子域的域应该保持不变。仅当完整域具有子域时才应触及。换句话说,两个或更多“.”。

google.com 必须保留 google.com 输入:

google.com
mail.google.com

预期输出:

google.com
google.com

答案1

如果您想删除第一个子域:

cut -d . -f 2- input

如果您有多个级别的子域,sub2.sub1.domain.com您可以cut结合使用 来rev保留域的最后两个元素:

rev input | cut -d . -f -2 |  rev

答案2

样本数据

www.google.com
prep.ai.mit.edu

保留最后两个顶级域名,

使用sed

sed 's/.*\.\(.*\..*\)/\1/'

在哪里

  • .*\.贪婪匹配任何字符(包括点)和点
  • \( \)记住匹配的字符串
  • .*\..*多次使用任意字符(1),多次使用点任意字符
  • (1) 由于上面的贪婪,不会匹配点。
  • \1回忆起第一个记住的字符串

使用(gnu)grep

grep -Eo '[^.]*.[^.]*$' data
google.com
mit.edu
  • 正则表达式模式 ( [^.]*.[^.]*$) 的读法大部分如上,除了$哪个锚点位于行尾。

删除第一个子域,使用sed(保留信息,规范已更改)

sed -e 's/^[^.]*\.//' data
google.com
ai.mit.edu

在哪里

  • ^[^.]*\.读作^行首,[^.]而不是一个点.*多次读作\. 一个点
  • 被什么都取代了。
  • 如评论中所述,sed可以缩短为's/[^.]*.//'(前提是行不以点开头)。

答案3

如果我们可以确定域将是.该行的最后两个分隔字段,您可以使用:

$ awk -F. -v OFS='.' '{print $(NF-1),$NF}' file
stackexchange.com
example.org
example.tld

或者sed

$ sed 's/.*\.\([^.]*\..*\)$/\1/' file
stackexchange.com
example.org
example.tld

而且,如果你sed支持的话-E,稍微干净一些:

 sed -E 's/.*\.([^.]*\..*)$/\1/' file
stackexchange.com
example.org
example.tld

答案4

使用标准sed删除除最后一个和倒数第二个组件之外的所有内容:

sed 's/.*\.\(.*\..*\)/\1/'

不幸的是,这个正则表达式看起来就像暴风雨过后的森林。让我们分步骤构建它:

  • .*\.是任意数量的字符(包括点),以点结尾
  • 在表达式的后面,我们需要另一个点,因此.*\.将匹配从开始到倒数第二个点的所有内容
  • 现在我们确信该行的其余部分只有一个点(字面意义上的点,因此.*\..*足以匹配其余部分
  • 我们把这个残骸放在里面\(\),这样它就可以在更换时被回收利用\1,而其他的东西都被扔掉了。

视觉解释:

subdomain.domain.tld
sub1.sub2.domain.tld
`--v----´ `-v--´ `v´
   .*   \.  .* \. .*

相关内容