Làm thế nào để có được phần cuối của liên kết http trong Bash?


25

Tôi có một liên kết http:

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

và tôi muốn lưu phần cuối file.jar vào biến, vì vậy chuỗi đầu ra là "file.jar".

Điều kiện : liên kết có thể có độ dài khác nhau, vd:

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

Tôi đã thử nó theo cách đó:

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

, nhưng vấn đề là độ dài của URL, vì vậy tôi cần một lệnh có thể được sử dụng cho bất kỳ độ dài URL nào.

Câu trả lời:


51

Sử dụng awkcho việc này sẽ có hiệu quả, nhưng đó là kiểu săn hươu với một con chó săn. Nếu bạn đã để sẵn URL, việc thực hiện những gì bạn muốn là khá đơn giản nếu bạn đặt nó vào một biến shell và sử dụng bashthay thế tham số tích hợp sẵn:

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

Cách thức hoạt động này là bằng cách xóa một tiền tố phù hợp với '* /', đây là điều mà ##nhà điều hành thực hiện:

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

Bất kỳ loại giải thích để đi với điều đó?
hỏi

Chắc chắn rồi. Điều đó sẽ làm gì?
DopeGhoti

Điều đó thật tuyệt :)
hỏi

2
Nếu bạn muốn truy vấn dải dây, bạn có thể đầu tiên gán cho một biến ví dụ như trung gian file=${myurl##*/}, sau đó sử dụng tham lam ngược khớp để sao lưu vào ?(đừng quên để thoát khỏi nó!), Ví dụ:echo ${file%%\?*}
Doktor J

21

basenamevà cũng dirnamehoạt động tốt cho các 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 Brilliant, nó hoạt động vì một URL và PATH và cả URI.
Tulains Córdova

1
@ TulainsCórdova một đường dẫn không phải là URI ; điều này hoạt động vì basenamedirnamephân tách chuỗi trên /, và điều đó cũng xảy ra với URL, ít nhất là miễn là chúng không có phần cục bộ (nói chung không phải với URI).
Stephen Kitt

Trong bài viết trên Wikipedia về URI, họ đưa ra những điều sau đây làm ví dụ giá trị của tham chiếu URI: /relative/URI/with/absolute/path/to/resource.txt, relative/path/to/resource.txt, ../../../resource.txtresource.txt en.wikipedia.org/wiki/...
Tulains Córdova

1
@ TulainsCórdova Wikipedia không sai, /relative/pathcó thể là đường dẫn hệ thống tệp hoặc URI tương đối. Nhưng cái nào trong số đó phụ thuộc vào bối cảnh. Khi nó được sử dụng làm đường dẫn hệ thống tệp, nó không phải là URI. Khi được sử dụng làm URI, nó không phải là đường dẫn hệ thống tệp. Nói đó là một URI chỉ vì nó phù hợp với cú pháp cũng giống như nói mỗi từ trong nhận xét này cũng là một URI.
hvd

11

Với awk, bạn có thể sử dụng $NF, để lấy trường cuối cùng, bất kể số lượng trường:

awk -F / '{print $NF}'

Nếu bạn lưu trữ chuỗi đó trong biến shell, bạn có thể sử dụng:

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

6

Hầu hết các câu trả lời được đăng không mạnh mẽ trên các URL chứa chuỗi truy vấn hoặc mục tiêu, chẳng hạn như, ví dụ như sau:

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

Python có phân tích cú pháp URL trong thư viện chuẩn của nó; dễ dàng hơn để cho nó làm điều đó. Ví dụ,

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

Bạn có thể nén nó thành một python3 -cđể sử dụng trong tập lệnh 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])'

(Bạn cũng có thể giữ tập lệnh bị hỏng, vì tính dễ đọc. 'Sẽ cho phép bạn đặt dòng mới vào.)

Tất nhiên, bây giờ tập lệnh shell của bạn có sự phụ thuộc vào Python.

(Tôi không chắc lắm về việc nếu cố xử lý các trường hợp trong đó thành phần đường dẫn của URL là gốc ( /); điều chỉnh / kiểm tra nếu điều đó quan trọng với bạn.)


1

Một phương pháp là revURL sau đó cắt trường và sau đó revmột lần nữa. ví dụ:

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

Đầu ra:

file.jar 

Ví dụ 2:

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

Đầu ra:

file.jar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.