Bashでhttpリンクの最後の部分を取得する方法は?


25

httpリンクがあります:

http://www.test.com/abc/def/efg/file.jar 

最後の部分のfile.jarを変数に保存したいので、出力文字列は「file.jar」です。

条件:リンクの長さは異なる場合があります。例:

http://www.test.com/abc/def/file.jar.

私はそのようにしてみました:

awk -F'/' '{print $7}'

、しかし問題はURLの長さなので、どんなURLの長さでも使用できるコマンドが必要です。

回答:


51

これを使用awkすることは機能しますが、それはhow弾砲による鹿狩りのようなものです。既にURLを公開している場合、それをシェル変数に入れてbashの組み込みパラメーター置換を使用すると、必要な処理を簡単に実行できます。

$ myurl='http://www.example.com/long/path/to/example/file.ext'
$ echo ${myurl##*/}
file.ext

これが機能する方法は、「* /」に貪欲に一致するプレフィックスを削除することです。これは、##オペレーターが行うことです:

${haystack##needle} # removes any matching 'needle' from the
                    # beginning of the variable 'haystack'

それに伴う説明はありますか?
疑問符

確かに。それはしますか?
DopeGhoti

それは素晴らしいです:)
疑問符

2
あなたは、クエリ文字列を削除したい場合は、あなたが最初の中間変数などに割り当てることができfile=${myurl##*/}、その後にバックアップする貪欲逆マッチングを使用して?(!それをエスケープすることを忘れないでください)、例えばecho ${file%%\?*}
ドクトルJ

21

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

+1ブリリアント、URLとPATHおよび両方のURIで機能します。
Tulainsコルドバ

1
@TulainsCórdovaパスはURIではありません; これが機能するのはbasenamedirname文字列を/で分割し、少なくともローカル部分を持たない限り(ただし一般的なURIではなく)、URLでも機能するためです。
スティーブンキット

:URIに関するWikipediaの記事の中で、彼らは有効なURI参照の例として、以下のものを与え/relative/URI/with/absolute/path/to/resource.txtrelative/path/to/resource.txt../../../resource.txtおよびresource.txt en.wikipedia.org/wiki/...
Tulainsコルドバ

1
@TulainsCórdovaWikipediaは間違いではなく/relative/path、ファイルシステムパスまたは相対URIのいずれかです。しかし、それらのどれがコンテキストに依存します。ファイルシステムパスとして使用される場合、URIではありません。URIとして使用される場合、ファイルシステムパスではありません。たまたま構文に一致するという理由だけでURIだと言うのは、このコメントの各単語もURIだと言うようなものです。
hvd

11

ではawk$NFフィールドの数に関係なく、を使用して最後のフィールドを取得できます。

awk -F / '{print $NF}'

その文字列をシェル変数に保存する場合、次を使用できます。

a=http://www.test.com/abc/def/efg/file.jar
printf '%s\n' "${a##*/}"

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])

python3 -cシェルスクリプトで使用するために、それを1つに圧縮できます。

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])'

(読みやすくするために、スクリプトを分割することもでき'ます。改行を挿入できます。)

もちろん、シェルスクリプトはPythonに依存しています。

(URLのパスコンポーネントがルート(/)であるケースを処理しようとするかどうかについては少し確信が持てません。それが問題になる場合は調整/テストしてください。)


1

1つの方法はrev、URLを使用してからフィールドをカットし、rev再度カットすることです。例えば:

echo 'http://www.test.com/abc/def/efg/file.jar ' | rev | cut -d '/' -f 1 | rev

出力:

file.jar 

例2:

echo 'http://www.test.com/abc/cscsc/sccsc/def/efg/file.jar ' | rev | cut -d '/' -f 1 | rev

出力:

file.jar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.