如何从网址中提取域名?

Ben*_*ith 38 regex url bash

如何使用bash从URL中提取域名?喜欢:http://example.com/到example.com必须适用于任何tld,而不仅仅是.com

小智 72

您可以使用简单的AWK方式提取域名,如下所示:

echo http://example.com/index.php | awk -F[/:] '{print $4}'
Run Code Online (Sandbox Code Playgroud)

OUTPUT: example.com

:-)

  • `echo http://example.com:3030/index.php | awk -F /'{print $ 3}'``example.com:3030` :-( (5认同)
  • 处理带端口和不带端口的URL:`awk -F [/:]'{print $ 4}'` (3认同)
  • 我用这个了它 - 回声`HTTP:// www.example.com/somedir/someotherdir/index.html` | 切-d '/' -f1,2,3给`HTTP:// www.example.com` (2认同)

mus*_*XXX 18

basename "http://example.com"
Run Code Online (Sandbox Code Playgroud)

当然,这不适用于这样的URI:http://www.example.com/index.html但您可以执行以下操作:

basename $(dirname "http://www.example.com/index.html")
Run Code Online (Sandbox Code Playgroud)

或者对于更复杂的URI:

echo "http://www.example.com/somedir/someotherdir/index.html" | cut -d'/' -f3
Run Code Online (Sandbox Code Playgroud)

-d表示"分隔符",-f表示"字段"; 在上面的示例中,由正斜杠'/'分隔的第三个字段是www.example.com.

  • 我喜欢cut -d'/' - f3因为它简单. (2认同)

小智 16

$ URI="http://user:pw@example.com:80/"
$ echo $URI | sed -e "s/[^/]*\/\/\([^@]*@\)\?\([^:/]*\).*/\2/"
example.com
Run Code Online (Sandbox Code Playgroud)

http://en.wikipedia.org/wiki/URI_scheme

  • 这可以使用或不使用端口,深路径并且仍在使用bash.虽然它不适用于mac. (3认同)
  • 我使用你的建议和一些额外的东西来去除可能在 url 中的任何子域 ->> `echo http://www.mail.example.com:3030/index.php | sed -e "s/[^/]*\/\/\([^@]*@\)\?\([^:/]*\).*/\2/" | awk -F。'{打印 $(NF-1) "。" $NF}'` 所以我基本上在点处切断你的输出,并取最后一列和倒数第二列,然后用点修补它们。 (2认同)

key*_*oxy 10

echo $URL | cut -d'/' -f3 | cut -d':' -f1
Run Code Online (Sandbox Code Playgroud)

适用于网址:

http://host.example.com
http://host.example.com/hi/there
http://host.example.com:2345/hi/there
http://host.example.com:2345
Run Code Online (Sandbox Code Playgroud)


F. *_*uri 8

3 个答案:短URL 解析 + )和完整TLD 提取器

关于问题的评论:

问题代表正则,但目标是根据字符拆分字符串/XY 问题,使用正则表达式来完成这种工作是矫枉过正的!

首先是 Posix shell

我们可以使用更快的参数扩展,而不是使用fork到另一个二进制文件,例如awkperl或else :cut

URL="http://example.com/some/path/to/page.html"
prot="${URL%%:*}"
link="${URL#$prot://}"
domain="${link%%/*}"
link="${link#$domain}"
printf '%-8s: %s\n' Protocol "${prot%:}" Domain "$domain" Link "$link"
Run Code Online (Sandbox Code Playgroud)
Protocol: http
Domain  : example.com
Link    : /some/path/to/page.html
Run Code Online (Sandbox Code Playgroud)

注意:即使使用file URL也可以工作:

URL=file:///tmp/so/test.xml 
prot="${URL%%:*}"
link="${URL#$prot://}"
domain="${link%%/*}"
link="${link#$domain}"
printf '%-8s: %s\n' Protocol "${prot%:}" Domain "$domain" Link "$link"
Run Code Online (Sandbox Code Playgroud)
URL=file:///tmp/so/test.xml 
prot="${URL%%:*}"
link="${URL#$prot://}"
domain="${link%%/*}"
link="${link#$domain}"
printf '%-8s: %s\n' Protocol "${prot%:}" Domain "$domain" Link "$link"
Run Code Online (Sandbox Code Playgroud)

read使用 bash 的 url 部分

由于这个问题被标记为并且没有答案地址read简短、快速且可靠的解决方案:

Protocol: file
Domain  : 
Link    : /tmp/so/test.xml
Run Code Online (Sandbox Code Playgroud)

就这样。由于 read 是内置的,这是最快的方法!(** 见评论

从那里你可以

URL="http://example.com/some/path/to/page.html"

IFS=/ read -r prot _ domain link <<<"$URL"
Run Code Online (Sandbox Code Playgroud)
printf '%-8s: %s\n' Protocol "${prot%:}" Domain "$domain" Link "/$link"
Run Code Online (Sandbox Code Playgroud)

您甚至可以检查端口:

Protocol: http
Domain  : example.com
Link    : /some/path/to/page.html
Run Code Online (Sandbox Code Playgroud)
URL="http://example.com:8000/some/path/to/page.html"
IFS=/ read -r prot _ domain link <<<"$URL"
IFS=: read -r domain port <<<"$domain"

printf '%-8s: %s\n' Protocol "${prot%:}" Domain "$domain" Port "$port" Link "/$link"
Run Code Online (Sandbox Code Playgroud)

使用默认端口进行完整解析:

Protocol: http
Domain  : example.com
Port    : 8000
Link    : /some/path/to/page.html
Run Code Online (Sandbox Code Playgroud)
URL="https://stackoverflow.com/questions/2497215/how-to-extract-domain-name-from-url"
declare -A DEFPORTS='([http]=80 [https]=443 [ipp]=631 [ftp]=21)'
IFS=/ read -r prot _ domain link <<<"$URL"
IFS=: read -r domain port <<<"$domain"

printf '%-8s: %s\n' Protocol "${prot%:}" Domain "$domain" \
    Port  "${port:-${DEFPORTS[${prot%:}]}}" Link "/$link"
Run Code Online (Sandbox Code Playgroud)

完整的顶级域提取器(在纯 bash 中):

关于公共后缀@tripleee的评论

有一个分支wget仅在函数初始化时执行一次:

Protocol: https
Domain  : stackoverflow.com
Port    : 443
Link    : /questions/2497215/how-to-extract-domain-name-from-url
Run Code Online (Sandbox Code Playgroud)

然后

declare -A TLD='()'
initTld () { 
    local tld
    while read -r tld; do
        [[ -n ${tld//*[ \/;*]*} ]] && TLD["${tld#\!}"]=''
    done < <(
      wget -qO - https://publicsuffix.org/list/public_suffix_list.dat
    )
}
tldExtract () { 
    if [[ $1 == -v ]] ;then local _tld_out_var=$2;shift 2;fi
    local dom tld=$1 _tld_out_var
    while [[ ! -v TLD[${tld}] ]] && [[ -n $tld ]]; do
        IFS=. read -r dom tld <<< "$tld"
    done
    if [[ -v _tld_out_var ]] ;then
        printf -v $_tld_out_var '%s %s' "$dom" "$tld"
    else
        echo "$dom $tld"
    fi
}
initTld ; unset -f initTld
Run Code Online (Sandbox Code Playgroud)


Dar*_*tle 7

#!/usr/bin/perl -w
use strict;

my $url = $ARGV[0];

if($url =~ /([^:]*:\/\/)?([^\/]+\.[^\/]+)/g) {
  print $2;
}
Run Code Online (Sandbox Code Playgroud)

用法:

./test.pl 'https://example.com'
example.com

./test.pl 'https://www.example.com/'
www.example.com

./test.pl 'example.org/'
example.org

 ./test.pl 'example.org'
example.org

./test.pl 'example'  -> no output
Run Code Online (Sandbox Code Playgroud)

如果您只想要域而不是完整的主机+域,请使用以下内容:

#!/usr/bin/perl -w
use strict;

my $url = $ARGV[0];
if($url =~ /([^:]*:\/\/)?([^\/]*\.)*([^\/\.]+\.[^\/]+)/g) {
  print $3;
}
Run Code Online (Sandbox Code Playgroud)


Arm*_*and 7

sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_'
Run Code Online (Sandbox Code Playgroud)

例如

$ sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_' <<< 'http://example.com'
example.com

$ sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_' <<< 'https://example.com'
example.com

$ sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_' <<< 'http://example.com:1234/some/path'
example.com

$ sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_' <<< 'http://user:pass@example.com:1234/some/path'
example.com

$ sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_' <<< 'http://user:pass@example.com:1234/some/path#fragment'
example.com

$ sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_' <<< 'http://user:pass@example.com:1234/some/path#fragment?params=true'
example.com
Run Code Online (Sandbox Code Playgroud)


小智 6

而不是使用正则表达式来执行此操作,您可以使用python的urlparse:

 URL=http://www.example.com

 python -c "from urlparse import urlparse
 url = urlparse('$URL')
 print url.netloc"
Run Code Online (Sandbox Code Playgroud)

您可以像这样使用它,也可以将它放在一个小脚本中.但是,这仍然需要一个有效的方案标识符,查看您的注释,您的输入不一定提供.您可以指定默认方案,但urlparse期望netloc以'//':

url = urlparse('// www.example.com/index.html','http')

所以你必须手动添加这些,即:

 python -c "from urlparse import urlparse
 if '$URL'.find('://') == -1 then:
   url = urlparse('//$URL','http')
 else:
   url = urlparse('$URL')
 print url.netloc"
Run Code Online (Sandbox Code Playgroud)


gho*_*g74 5

关于如何获取这些网址的信息很少...请下次显示更多信息。网址等中是否有参数等...同时,只需对示例网址进行简单的字符串处理

例如

$ s="http://example.com/index.php"
$ echo ${s/%/*}  #get rid of last "/" onwards
http://example.com
$ s=${s/%\//}  
$ echo ${s/#http:\/\//} # get rid of http://
example.com
Run Code Online (Sandbox Code Playgroud)

其他方式,使用sed(GNU)

$ echo $s | sed 's/http:\/\///;s|\/.*||'
example.com
Run Code Online (Sandbox Code Playgroud)

使用awk

$ echo $s| awk '{gsub("http://|/.*","")}1'
example.com
Run Code Online (Sandbox Code Playgroud)

  • 我的方法不起作用,因为您的示例网址不同!并且您没有提供有关要解析的网址类型的更多信息!您应该清楚地写下您的问题,并提供输入示例并描述您下次想要的输出! (3认同)