如何在 Bash 中获取 http 链接的最后一部分?

Fun*_*mas 36 bash awk shell-script cut

我有一个 http 链接:

http://www.test.com/abc/def/efg/file.jar 
Run Code Online (Sandbox Code Playgroud)

我想将最后一部分 file.jar 保存到变量中,所以输出字符串是“file.jar”。

条件:链接可以有不同的长度,例如:

http://www.test.com/abc/def/file.jar.
Run Code Online (Sandbox Code Playgroud)

我是这样试的:

awk -F'/' '{print $7}'
Run Code Online (Sandbox Code Playgroud)

,但问题是 URL 的长度,所以我需要一个可用于任何 URL 长度的命令。

Dop*_*oti 67

使用awk它会起作用,但它有点像用榴弹炮猎鹿。如果您已经拥有裸露的 URL,那么将它放入一个 shell 变量并使用bash的内置参数替换,就可以很简单地做您想做的事:

$ myurl='http://www.example.com/long/path/to/example/file.ext'
$ echo ${myurl##*/}
file.ext
Run Code Online (Sandbox Code Playgroud)

其工作方式是删除贪婪地匹配“*/”的前缀,这就是##运算符所做的:

${haystack##needle} # removes any matching 'needle' from the
                    # beginning of the variable 'haystack'
Run Code Online (Sandbox Code Playgroud)

  • 如果你想剥离查询字符串,你可以先赋值给一个中间变量,例如`file=${myurl##*/}`,然后使用贪婪反向匹配来备份到`?`(不要忘记逃脱它!),例如`echo ${file%%\?*}` (2认同)

Fed*_*rev 24

basename并且也dirname适用于 URL:

> url="http://www.test.com/abc/def/efg/file.jar"
> basename "$url"; basename -s .jar "$url"; dirname "$url"
file.jar
file
http://www.test.com/abc/def/efg
Run Code Online (Sandbox Code Playgroud)


cuo*_*glm 13

使用awk, 您可以使用$NF, 获取最后一个字段,无论字段数量如何:

awk -F / '{print $NF}'
Run Code Online (Sandbox Code Playgroud)

如果将该字符串存储在 shell 变量中,则可以使用:

a=http://www.test.com/abc/def/efg/file.jar
printf '%s\n' "${a##*/}"
Run Code Online (Sandbox Code Playgroud)


Tha*_*tos 6

大多数发布的答案对包含查询字符串或目标的 URL 并不可靠,例如,以下内容:

https://example.com/this/is/a/path?query#target

Python 在其标准库中有 URL 解析;让它这样做更容易。例如,

from urllib import parse
import sys
path = parse.urlparse(sys.stdin.read().strip()).path
print("/" if not path or path == "/" else path.rsplit("/", 1)[-1])
Run Code Online (Sandbox Code Playgroud)

您可以将其压缩为单个python3 -c以在 shell 脚本中使用:

echo 'https://example.com/this/is/a/path/componets?query#target' \
    | python3 -c 'from urllib import parse; import sys; path = parse.urlparse(sys.stdin.read().strip()).path; print("/" if not path or path == "/" else path.rsplit("/", 1)[-1])'
Run Code Online (Sandbox Code Playgroud)

(为了可读性,您也可以保持脚本分解。'将让您放入换行符。)

当然,现在您的 shell 脚本依赖于 Python。

(我有点不确定是否尝试处理 URL 的路径组件是根 ( /) 的情况;如果这对您很重要,请调整/测试。)