awk substr을 사용하여 마지막 필드 가져 오기


101

awk파일에 대한 절대 경로가 주어진 파일 이름을 가져 오는 데 사용하려고 합니다.
예를 들어, 입력 경로가 주어지면 /home/parent/child/filename얻고 filename 싶습니다.

awk -F "/" '{print $5}' input

완벽하게 작동합니다.
그러나 $5내 입력에 다음 구조가 있으면 잘못된 하드 코딩 입니다.

/home/parent/child1/child2/filename

따라서 일반적인 솔루션은 항상 마지막 필드 (파일 이름)를 가져와야합니다.

awk substr 함수로이 작업을 수행하는 간단한 방법이 있습니까?


2
누군가가 사용하는 basename것이 공식적인 방법이기 awk때문에 이것을 사용 하는 것은 가볍게 두는 것이 좋지 않습니다. : D
Kashyap

답변:


209

awk정의 할 수있는 필드 구분 기호를 기반으로 필드의 행 을 분할 하는 사실을 사용하십시오 . 따라서 필드 구분 기호를 정의하면 /다음과 같이 말할 수 있습니다.

awk -F "/" '{print $NF}' input

NF현재 레코드의 필드 수 를 나타내는 것처럼 $NF인쇄는 마지막 레코드를 인쇄 하는 것을 의미합니다.

따라서 다음과 같은 파일이 주어집니다.

/home/parent/child1/child2/child3/filename
/home/parent/child1/child2/filename
/home/parent/child1/filename

다음과 같이 출력됩니다.

$ awk -F"/" '{print $NF}' file
filename
filename
filename

3
완벽하게 작동합니다. $ NF 변수에 대해 생각하지 않았습니다. 귀하의 즉각적이고 간단하고 효과적인 답변에 감사드립니다.
Mari

6
penult one의 경우 $(NF-1).
Itachi

1
일부 도커 명령과 함께 작동하는 스크립트를 작성했으며 이것이 트릭을 수행했습니다. 감사!
Harlin 2011

31

이 경우 다음 basename대신 사용하는 것이 좋습니다 awk.

 $ basename /home/parent/child1/child2/filename
 filename

4
@Mari FYI dirname 는 반대를 수행하고 경로가 아닌 파일을 제거합니다.
Chris Seymour

5

또 다른 옵션은 bash 매개 변수 대체 를 사용하는 것 입니다.

$ foo="/home/parent/child/filename"
$ echo ${foo##*/}
filename
$ foo="/home/parent/child/child2/filename"
$ echo ${foo##*/}
filename

5

Perl 솔루션에 열려있는 경우 여기에 fedorqui의 awk 솔루션과 유사한 솔루션이 있습니다.

perl -F/ -lane 'print $F[-1]' input

-F/지정 /필드 분리 그대로
$F[-1]마지막 요소 @F자동 구분 어레이


1
감사. 이것은 내가 마지막으로 하나의 필드를 얻는 데 도움이되었습니다. perl -F "/"-lane 'print $ F [-2]'입력
riderchap

이것은 파이프 입력에서 수신 할 때 나를 위해 일했습니다. 펄을 완전히 잊었습니다.
Christopher

3

basename 답변에 대한 주석이어야하지만 요점이 충분하지 않습니다.

큰 따옴표를 사용하지 않으면 basename공백 문자가있는 경로에서 작동하지 않습니다.

$ basename /home/foo/bar foo/bar.png
bar

좋아 따옴표 ""

$ basename "/home/foo/bar foo/bar.png"
bar.png

파일 예

$ cat a
/home/parent/child 1/child 2/child 3/filename1
/home/parent/child 1/child2/filename2
/home/parent/child1/filename3

$ while read b ; do basename "$b" ; done < a
filename1
filename2
filename3

3

내가 3 년 늦었다는 건 알지만 .. 매개 변수 확장을 고려해야합니다. 내장되어 있고 더 빠릅니다.

입력이 var에 있으면 $ var1이라고 가정 해 봅시다 ${var1##*/}. 아래를보세요

$ var1='/home/parent/child1/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/child3/filename'
$ echo ${var1##*/}
filename

2

5 년 후처럼 모든 제안에 감사 드리며 다음과 같은 방식으로이 작업을 수행했습니다.

$ echo /home/parent/child1/child2/filename | rev | cut -d '/' -f1 | rev
filename

더 나은 매너가 있다는 것을 알게되어 기쁩니다


-1

다음을 사용할 수도 있습니다.

    sed -n 's/.*\/\([^\/]\{1,\}\)$/\1/p'

또는

    sed -n 's/.*\/\([^\/]*\)$/\1/p'

1
이 시점에서 아무도는 :) 못 생기고 상대적이다 아마 때문에,이 대답을 upvoted없는 것
요시프 로댕
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.