【问题标题】:bash (grep|awk|sed) - Extract domains from a filebash (grep|awk|sed) - 从文件中提取域
【发布时间】:2014-06-03 09:12:29
【问题描述】:

我需要从文件中提取域。

domains.txt:

eofjoejfej fjpejfe http://ejej.dm1.com dêkkde
ojdoed www.dm2.fr doejd eojd oedj eojdeo
http://dm3.org ieodhjied oejd oejdeo jd
ozjpdj eojdoê jdeojde jdejkd http://dm4.nu/
io d oed 234585 http://jehrhr.dm5.net/hjrehr
[2014-05-31 04:05] eohjpeo jdpiehd pe dpeoe www.dm6.uk/jehr

我需要得到:

dm1.com dm2.fr dm3.org dm4.nu dm5.net dm6.co.uk

【问题讨论】:

  • I need to get ....!你的问题在哪里? 2) 你怎么想拥有dm6.co.uk?它是否存在于输入文件中?
  • 到目前为止你有什么尝试?据我所知,问题在于如何确定域的正则表达式。您的网址是遵循特定模式还是完全随机?否则像http://my.cool.custom.name.dm1.co.uk 这样的名字将很难匹配

标签: bash awk sed grep


【解决方案1】:

试试这个 sed 命令,

$ sed -r 's/.*(dm[^\.]*\.[^/ ]*).*/\1/g' file
dm1.com
dm2.fr
dm3.org
dm4.nu
dm5.net
dm6.uk

【讨论】:

  • 我们确定它们每行最多一次吗?
  • 根据操作员的输入发布。
【解决方案2】:

这有点长,但应该可以:

grep -oE "http[^ ]*|www[^ ]*" file | sed -e 's|http://||g' -e 's/^www\.//g' -e 's|/.*$||g' -re 's/^.*\.([^\.]+\.[^\.]+$)/\1/g'

输出:

dm1.com
dm2.fr
dm3.org
dm4.nu
dm5.net
dm6.uk

【讨论】:

    【解决方案3】:

    使用 grep 和 sed 的未优化方法:

    grep -oE '[[:alnum:]]+[.][[:alnum:]_.-]+' file | sed 's/www.//'
    

    输出:

    ejej.dm1.com
    dm2.fr
    dm3.org
    dm4.nu
    jehrhr.dm5.net
    dm6.uk
    

    【讨论】:

    • ejej.dm1.com 不是域名。 OP想提取dm1.com
    • @Ploutox 是的,这很明显。不过,他没有明确地说出来,所以给一个快速的答案以供更改是不错的。我希望你注意到“Unrefined”这个词。
    【解决方案4】:

    gawk 的回答:

    LC_ALL=C gawk -d -v RS="[[:space:]]+" -v FS="." '
      {
        # Remove the http prefix if it exists
        sub( /http:[/][/]/, "" )
    
        # Remove the path
        sub( /[/].*$/, "" )
    
        # Does it look like a domain?
        if ( /^([[:alnum:]]+[.])+[[:alnum:]]+$/ ) {
    
          # Print the last 2 components of the domain name
          print $(NF-1) "." $NF
    
        }
    
      }' file
    

    一些注意事项:

    • 使用RS="[[:space:]]" 允许我们独立处理每组字母。
    • LC_ALL=C 强制 [[:alnum:]] 仅使用 ASCII 码(gawk 4+ 不再需要这样做)。

    【讨论】:

      【解决方案5】:

      这很有用:

      grep -Pho "(?<=http://)[^(\"|'|[:space:])]*" file.txt | sed 's/www.//g' | grep -Eo '[[:alnum:]]{1,}\.[[:alnum:]]{1,}[.]{0,1}[[:alnum:]]{0,}' | sort | uniq
      

      首先 grep 得到 'http://www.example.com' 括在单引号或双引号中,但仅提取域。第二,使用'sed'我删除'www.',第三个提取以'.'分隔的域名并且在两个或三个字母数字字符的块中。最后,输出被排序为仅显示每个域的单个实例

      【讨论】:

        【解决方案6】:

        为了能够删除子域,您必须首先对其进行验证,因为如果您剪切列会影响 TLD。然后你必须做 3 个步骤。

        第一步:清理domains.txt

        grep -oiE '([a-zA-Z0-9][a-zA-Z0-9-]{1,61}\.){1,}(\.?[a-zA-Z]{2,}){1,}' domains.txt | sed -r 's:(^\.*?(www|ftp|ftps|ftpes|sftp|pop|pop3|smtp|imap|http|https)[^.]*?\.|^\.\.?)::gi' | sort -u > capture
        

        内容capture

        ejej.dm1.com
        dm2.fr
        dm3.org
        dm4.nu
        jehrhr.dm5.net
        dm6.uk
        

        第 2 步:下载并过滤 TLD 列表:

        wget https://raw.githubusercontent.com/publicsuffix/list/master/public_suffix_list.dat
        grep -v "//" public_suffix_list.dat | sed '/^$/d; /#/d' | grep -v -P "[^a-z0-9_.-]" |  sed 's/^\.//' |  awk '{print "." $1}' |  sort -u > tlds.txt
        

        到目前为止,您有两个列表(capturetlds.txt

        第 3 步:下载并运行此 python 脚本:

        wget https://raw.githubusercontent.com/maravento/blackweb/master/bwupdate/tools/parse_domain_tld.py && chmod +x parse_domain_tld.py && python parse_domain_tld.py | sort -u
        

        出来:

        dm1.com
        dm2.fr
        dm3.org
        dm4.nu
        dm5.net
        dm6.uk
        

        来源:blackweb

        【讨论】:

          猜你喜欢
          • 2021-11-28
          • 2018-08-25
          • 2012-08-02
          • 2018-08-23
          • 1970-01-01
          • 2012-08-13
          • 2020-12-04
          • 1970-01-01
          • 2020-09-27
          相关资源
          最近更新 更多