如何删除文本文件中的所有子域?我想我需要删除之前的所有内容,包括“.”?
输入:
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´
.* \. .* \. .*