답변:
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
) 잠재적으로 느릴 수 있습니다.
-a
on 옵션 을 사용하면 basename
한 번의 호출로 여러 파일 이름을 사용할 수 있습니다. 즉,을 사용 xargs
하지 않고 -n 1
경로를 훨씬 더 적은 수의 호출로 그룹화하여 basename
보다 효율적으로 사용할 수 있습니다.
예:
find /dir1 -type f -print0 | xargs -0 basename -a
여기 에는 파일과 디렉토리 이름 내부의 공백에 대처하기 위해 -print0
and -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
.)