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이것을 사용하면 효과가 있지만 곡사포로 사슴을 사냥하는 것입니다. 이미 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'

그것과 함께 할 어떤 종류의 설명?
Questionmark

확실한. 그럴까요?
DopeGhoti

: great
Questionmark

2
쿼리 문자열을 제거하려면 먼저 중간 변수에 할당 file=${myurl##*/}한 다음 욕심 많은 역 매칭을 사용하여 ?(이를 피하는 것을 잊지 마십시오!) 예를 들어echo ${file%%\?*}
Doktor 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 Córdova

1
@ TulainsCórdova 경로는 URI 가 아니다 ; 이것은 /에서 문자열을 분리 basename하고 dirname분할 하기 때문에 작동하며 URL에 로컬 부분이없는 한 URL에서도 작동합니다 (일반적으로 URI가 아님).
Stephen Kitt

: URI에 대한 Wikipedia 기사에서, 그들은 유효한 URI 참조의 예로 다음을주고 /relative/URI/with/absolute/path/to/resource.txt, relative/path/to/resource.txt, ../../../resource.txtresource.txt en.wikipedia.org/wiki/...
Tulains 코르도바

1
@ TulainsCórdova Wikipedia가 잘못되지 않았습니다 /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

파이썬은 표준 라이브러리에 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쉘 스크립트에서 사용하기 위해 하나로 압축 할 수 있습니다 .

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

(가독성을 위해 스크립트를 나눌 수도 있습니다. '개행을 넣을 수 있습니다.)

물론, 이제 쉘 스크립트는 파이썬에 의존합니다.

(URL 경로 구성 요소가 루트 ( /) 인 경우를 처리하려고하는지 여부는 확실하지 않습니다 . 중요한 경우 조정 / 테스트하십시오.)


1

한 가지 방법은 revURL에서 필드를 잘라낸 다음 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.