bash - 如何在 shell 脚本(sed/awk/etc)中删除多余的 www 子域?
问题描述
我需要删除多余的“www”。在不断增长的庞大域列表中添加前缀。这是示例:
# Type 1
domain1.tld
# Type 2
domain2.tld
www.domain2.tld
# Type 3
www.domain3.tld
sub.domain3.tld
foo.domain3.tld
www.sub.domain3.tld
# Expected
domain1.tld
domain2.tld
www.domain3.tld
sub.domain3.tld
foo.domain3.tld
由于列表已经包含超过 200 万行,因此唯一有效的方法是永远。
cp 1.txt 2.txt
while read line; do
sed "/www.$line/d" -i 2.txt
done < 1.txt
我正在使用 GNU utils 并且已经使用 sed、awk、comm 无济于事。
如何才能做到这一点?
解决方案
#! /bin/bash
awk -F. '{
if($1 != "www")
{
arr[$0]=1
}
else
if(arr[substr($0,5)] == 1)
{
next
}
print
}' file
看看这个,虽然我不确定如果有 200 万条记录它会如何工作。
更新:
说明:awk
表达式.
用作字段分隔符,所以假设如果行是www.sub.domain3.tld
, $1=www
, $2=sub
...</p>
www
它通过使它们在 array 中索引来标记所有不以开头的行arr
。假设线是sub.domain3.tld
,它将使其索引arr[sub.domain3.tld]
并存储e
在其中。现在对于以 开头的每一行www.
,它会剥离www.
并检查剩余的行是否存储在数组中,如果是,则不打印该行。
更新:
这将产生与提供输入的顺序无关的结果,尽管输出的顺序是混乱的:
#! /bin/bash
awk -F. '{
if ($1 != "www") {
domains["www."$0]=0
domains[$0]=1
}
else {
if (domains[$0] == ""){ domains[$0]=1 }
}
}
END {
for (domain in domains) {
if (domains[domain]) { print domain }
}
}' file
这应该以正确的顺序产生结果,而与提供输入的顺序无关:
#! /bin/bash
awk -F. '{
if ($1 != "www") {
redundant_domains["www."$0]=1
}
domains[NR]=$0
}
END {
for (i=1 ; i < NR ; ++i) {
if (!redundant_domains[domains[i]]) { print domains[i] }
}
}' file
推荐阅读
- c# - 并发 Web api 请求以及如何处理 ASP.NET 核心中的状态
- c# - 如何使用凭据从另一台计算机读取文本
- javascript - 如何在 Web Animation API 中为“from”设置动画
- android - 如何在 Preference.OnPreferenceChangeListener() 中正确调用方法
- jquery - DataTables如何在打印时隐藏标题?
- reactjs - 如何在单击按钮时重定向到另一个组件?
- javascript - Javascript数据解构
- c# - 如何在 Automapper 中通过目标路径获取映射的源路径
- r - 如何将从 xlsx 文件导入的列中的第一个单词复制到 Rstudio 并将其粘贴到网页的搜索框中?
- python - 如何修复 Django 模板/base.py 中的错误?