답변:
GNU에서는 find다음 -printf과 같은 매개 변수를 사용할 수 있습니다 .
find /dir1 -type f -printf "%f\n"
-o묵시적인 것보다 우선 순위가 낮기 -a때문에 종종 -o논쟁 을 그룹화하고 싶을 것입니다. )
find에 -printf 옵션이없는 경우 basename을 사용할 수도 있습니다.
find ./dir1 -type f -exec basename {} \;
... {} ';'
다음 -execdir과 같이 현재 파일을 자동으로 보유하는 다음 을 사용하십시오 {}.
find . -type f -execdir echo '{}' ';'
$PWD대신 사용할 수도 있습니다 .(일부 시스템에서는 전면에 추가 점이 생성되지 않음).
여전히 추가 점이 있으면 다음을 실행할 수 있습니다.
find . -type f -execdir basename '{}' ';'
-execdir utility [argument ...] ;
-execdir주는 동일-exec유틸리티는 디렉토리에서 실행됩니다 것을 제외하고 주 현재 파일을 보유 .
사용하는 경우 +대신 ;다음 {}유틸리티를 호출 할 때마다 가능한 한 많은 경로 이름으로 대체됩니다. 즉, 모든 파일 이름을 한 줄에 인쇄합니다.
./filename대신에 받고 filename있습니다. 필요에 따라 괜찮을 수도 있고 아닐 수도 있습니다.
$PWD대신에 사용해보십시오 ..
GNU find를 사용하는 경우
find . -type f -printf "%f\n"
또는 Ruby (1.9+)와 같은 프로그래밍 언어를 사용할 수 있습니다
$ ruby -e 'Dir["**/*"].each{|x| puts File.basename(x)}'
bash (최소 4) 솔루션을 좋아한다면
shopt -s globstar
for file in **; do echo ${file##*/}; done
파일 이름에 대해서만 일부 작업을 실행하려면 사용하기 basename가 어려울 수 있습니다.
예를 들면 다음과 같습니다.
find ~/clang+llvm-3.3/bin/ -type f -exec echo basename {} \;
basename 만 에코 /my/found/path합니다. 파일 이름을 실행하려면 원하는 것이 아닙니다.
그러나 xargs출력 할 수 있습니다 . 예를 들어 다른 디렉토리의 이름을 기반으로 디렉토리의 파일을 종료하려면 다음을 수행하십시오.
cd dirIwantToRMin;
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \; | xargs rm
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \;
-exec그리고 -execdir느린, xargs왕이다.
$ alias f='time find /Applications -name "*.app" -type d -maxdepth 5'; \
f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l; \
f -print0 | xargs -0 basename | wc -l
139
0m01.17s real 0m00.20s user 0m00.93s system
139
0m01.16s real 0m00.20s user 0m00.92s system
139
0m01.05s real 0m00.17s user 0m00.85s system
139
0m00.93s real 0m00.17s user 0m00.85s system
139
0m00.88s real 0m00.12s user 0m00.75s system
xargs평행도 도움이됩니다.
충분히 재미있게 난의 마지막 경우 설명 할 수 xargs없는이 -n1. 올바른 결과를 제공하며 가장 빠릅니다.¯\_(ツ)_/¯
( basename단 1 경로 인수를 취하는 그러나 xargs없이 실제로 5000 모든 ()을 보내드립니다 -n1.이 작동하지 않음을 리눅스와 오픈 BSD에 만 맥 OS ...)
리눅스 시스템에서 몇 가지 더 큰 숫자가 -execdir도움이되는 방법 을 알지만 병렬보다 훨씬 느립니다 xargs.
$ alias f='time find /usr/ -maxdepth 5 -type d'
$ f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l
2358
3.63s real 0.10s user 0.41s system
2358
1.53s real 0.05s user 0.31s system
2358
1.30s real 0.03s user 0.21s system
2358
0.41s real 0.03s user 0.25s system
find그것이 -execdir새로운 프로세스를 생성하는 것은 상대적으로 비용이 많이 드는 작업이기 때문에 그 가장 빠른됩니다.
다른 사람들이 지적했듯이 find및 을 결합 할 수 basename있지만 기본적으로 basename프로그램은 한 번에 하나의 경로에서만 작동하므로 실행 파일은 각 경로마다 한 번만 실행해야하며 ( find ... -exec또는을 사용하여 find ... | xargs -n 1) 잠재적으로 느릴 수 있습니다.
-aon 옵션 을 사용하면 basename한 번의 호출로 여러 파일 이름을 사용할 수 있습니다. 즉,을 사용 xargs하지 않고 -n 1경로를 훨씬 더 적은 수의 호출로 그룹화하여 basename보다 효율적으로 사용할 수 있습니다.
예:
find /dir1 -type f -print0 | xargs -0 basename -a
여기 에는 파일과 디렉토리 이름 내부의 공백에 대처하기 위해 -print0and -0(함께 사용해야 함)를 포함 시켰습니다 .
다음은 버전 xargs basename -a과 xargs -n1 basename버전 간의 타이밍 비교 입니다. (유사와 유사한 비교를 위해 여기에보고 된 타이밍은 초기 더미 실행 후이므로 파일 메타 데이터가 I / O 캐시에 이미 복사 된 후에 모두 수행됩니다.) cksum두 경우 모두, 출력이 사용 된 방법과 독립적이라는 것을 보여주기 위해.
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 basename -a | cksum'
2532163462 546663
real 0m0.063s
user 0m0.058s
sys 0m0.040s
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 -n 1 basename | cksum'
2532163462 546663
real 0m14.504s
user 0m12.474s
sys 0m3.109s
보시다시피 basename매번 실행을 피하는 것이 실제로 훨씬 빠릅니다 .
basename추가 명령 줄 인수가 필요없이 여러 파일 이름을 사용할 수 있음을 알 수 있습니다. 의 사용 -a여기에 리눅스에 있습니다. ( basename --version나에게 말한다 basename (GNU coreutils) 8.28.)