【发布时间】:2022-04-02 12:26:28
【问题描述】:
如何使用 bash 从 url 中提取域名? 喜欢:http://example.com/ 到 example.com 必须适用于任何顶级域名,而不仅仅是 .com
【问题讨论】:
-
不过,这是 Perl,而不是 Bash。
如何使用 bash 从 url 中提取域名? 喜欢:http://example.com/ 到 example.com 必须适用于任何顶级域名,而不仅仅是 .com
【问题讨论】:
您可以使用简单的AWK方式提取域名如下:
echo http://example.com/index.php | awk -F[/:] '{print $4}'
输出:example.com
:-)
【讨论】:
echo http://example.com:3030/index.php | awk -F/ '{print $3}' example.com:3030 :-(
: 以获取它,但它不够灵活,无法同时接受有端口和无端口。
http://www.example.com/somedir/someotherdir/index.html | cut -d'/' -f1,2,3 给出http://www.example.com
awk -F[/:] '{print $4}'
$ URI="http://user:pw@example.com:80/"
$ echo $URI | sed -e 's/[^/]*\/\/\([^@]*@\)\?\([^:/]*\).*/\2/'
example.com
【讨论】:
echo http://www.mail.example.com:3030/index.php | sed -e "s/[^/]*\/\/\([^@]*@\)\?\([^:/]*\).*/\2/" | awk -F. '{print $(NF-1) "." $NF}' 所以我基本上在点处截断你的输出并取最后一个和倒数第二个列并用点修补它们。
www. 子域
sed -e "s/[^/]*\/\/\([^@]*@\)\?\([^:/]*\)\(:\([0-9]\{1,5\}\)\)\?.*/\4/"
basename "http://example.com"
当然,这不适用于这样的 URI:http://www.example.com/index.html,但您可以执行以下操作:
basename $(dirname "http://www.example.com/index.html")
或者对于更复杂的 URI:
echo "http://www.example.com/somedir/someotherdir/index.html" | cut -d'/' -f3
-d 表示“分隔符”,-f 表示“字段”;在上面的示例中,由正斜杠“/”分隔的第三个字段是 www.example.com。
【讨论】:
echo "http://www.example.com:8080/somedir/someotherdir/index.html" | cut -d'/' -f3
http://www.example.com 通过运行 - echo http://www.example.com/somedir/someotherdir/index.html | cut -d'/' -f1,2,3
basename $(dirname 不起作用,如果 url 以域结尾,例如:basename $(dirname "http://www.example.com/") 将仅显示:http:
echo $URL | cut -d'/' -f3 | cut -d':' -f1
适用于 URL:
http://host.example.com
http://host.example.com/hi/there
http://host.example.com:2345/hi/there
http://host.example.com:2345
【讨论】:
abc.com 将保留为abc.com
host.example.com 而不是请求的域名 (example.com)。
sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_'
例如
$ 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
【讨论】:
HOST=$(sed -E -e 's_.*://([^/@]*@)?([^/:]+).*_\2_' <<< "$MYURL") 在 Bash 中很好
sed -E -e 's_.*://([^/@]*@)?([^/:]+)(.*)_\2_' <<< 'http://example.com' 这允许您从 url 获取路径 sed -E -e 's_.*://([^ /@]*@)?([^/:]+)(.*)_\3_' example.com/path/to/something'
#!/usr/bin/perl -w
use strict;
my $url = $ARGV[0];
if($url =~ /([^:]*:\/\/)?([^\/]+\.[^\/]+)/g) {
print $2;
}
用法:
./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
如果您只想要域而不是完整的主机 + 域,请改用:
#!/usr/bin/perl -w
use strict;
my $url = $ARGV[0];
if($url =~ /([^:]*:\/\/)?([^\/]*\.)*([^\/\.]+\.[^\/]+)/g) {
print $3;
}
【讨论】:
您可以使用 python 的 urlparse,而不是使用正则表达式来执行此操作:
URL=http://www.example.com
python -c "from urlparse import urlparse
url = urlparse('$URL')
print url.netloc"
您可以像这样使用它,也可以将它放在一个小脚本中。但是,这仍然需要一个有效的方案标识符,查看您的评论,您的输入不一定提供一个。您可以指定默认方案,但 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"
【讨论】:
关于如何获取这些网址的信息很少……请下次显示更多信息。 url中是否有参数等... 同时,只需对您的示例网址进行简单的字符串操作
例如
$ 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
其他方式, 使用 sed(GNU)
$ echo $s | sed 's/http:\/\///;s|\/.*||'
example.com
使用 awk
$ echo $s| awk '{gsub("http://|/.*","")}1'
example.com
【讨论】:
下面会输出“example.com”:
URI="http://user@example.com/foo/bar/baz/?lala=foo"
ruby -ruri -e "p URI.parse('$URI').host"
有关如何使用 Ruby 的 URI 类的更多信息,您必须咨询the docs。
【讨论】:
这是 node.js 的方式,它可以使用或不使用端口和深度路径:
//get-hostname.js
'use strict';
const url = require('url');
const parts = url.parse(process.argv[2]);
console.log(parts.hostname);
可以这样称呼:
node get-hostname.js http://foo.example.com:8080/test/1/2/3.html
//foo.example.com
【讨论】:
一种涵盖更多情况的解决方案将基于 sed 正则表达式:
echo http://example.com/index.php | sed -e 's#^https://\|^http://##' -e 's#:.*##' -e 's#/.*##'
这适用于以下网址:
http://example.com/index.php, http://example.com:4040/index.php, https://example.com/index.php
【讨论】:
借助 Ruby,您可以使用 Domainatrix 库/gem
http://www.pauldix.net/2009/12/parse-domains-from-urls-easily-with-domainatrix.html
需要“红宝石” 需要“域矩阵” s = 'http://www.champa.kku.ac.th/dir1/dir2/file?option1&option2' url = Domainatrix.parse(s) url.domain => “kku”很棒的工具! :-)
【讨论】:
没有任何子外壳或子进程的纯 Bash 实现:
# Extract host from an URL
# $1: URL
function extractHost {
local s="$1"
s="${s/#*:\/\/}" # Parameter Expansion & Pattern Matching
echo -n "${s/%+(:*|\/*)}"
}
例如extractHost "docker://1.2.3.4:1234/a/v/c" 将输出1.2.3.4
【讨论】: