foldername
확장자가 또는 이라는 test
폴더 atest
에 있는 모든 파일을 나열하고 싶습니다 btest
.
내 즉시 생각은 실행하는 것이 었습니다ls ./foldername/*.{a,b,}test
확장명에 아무 것도 없는 경우가 아니면 잘 작동합니다 . atest
이 경우 오류가 발생합니다 zsh: no matches found: ./foldername/*.atest
.
이 오류를 무시하고 존재하는 파일을 인쇄할 수 있는 방법이 있습니까?
zsh와 Bash 모두에서 작동하려면 이것이 필요합니다.
답변1
~ 안에
ls -d ./foldername/*.{a,b,}test
{a,b,...}
전역 연산자가 아닙니다. 이는 중괄호 확장이며 먼저 다음으로 확장됩니다.
ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test
그리고 각 glob은 개별적으로 확장되며, 일치하지 않는 glob이 있으면 명령이 예상대로 취소됩니다 zsh
(또는 fish
; 에서는 비슷한 동작을 얻으려면 옵션이 bash
필요합니다 ).failglob
여기서는 모든 파일과 일치하는 단일 glob을 사용하고 해당 하나의 glob이 어떤 파일과도 일치하지 않는 경우에만 명령을 취소하려고 합니다.
ls -d ./foldername/*.(a|b|)test
을 사용하고 싶지 않습니다 nullglob
. 일치하는 글로브가 없는 것처럼 ls
인수 없이 실행되므로 현재 디렉터리를 나열하세요. cshnullglob
일치하지 않는 glob을 제거하지만 모든 glob이 일치하지 않으면 여전히 명령을 취소하므로 점에서 더 좋습니다.
당신은 사용하고 싶지 않을 것입니다 nonomatch
. 왜냐하면 그것은 당신에게 부끄러운 행동을 초래할 것이기 때문입니다 bash
.
zsh
및 모두에서 작동하는 glob 대안의 경우 bash
ksh glob( set -o kshglob
in zsh
및 shopt -s extglob
in bash
)을 사용할 수 있습니다.
그런 다음 다음을 수행합니다.
ls -d ./foldername/*.@(a|b|)test
또는:
ls -d ./foldername/*.?([ab])test
일치하지 않을 때 glob이 문자 그대로 전달되는 것을 방지하려면 failglob
옵션을 추가하세요 .bash
ls
보다nullglob이 기본값이 아닌 이유는 무엇입니까?자세한 내용은.
답변2
다음을 사용하여 이 작업을 수행하는 것이 가장 좋습니다 find
.
find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'
답변3
나는 이 문제에 직면했고 먼저 ls 자체를 해킹하여 해결했습니다. 작업을 마쳤을 때 필요한 것은 Trival C 프로그램뿐이라는 것을 깨달았습니다.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
struct stat statbuf;
int i;
for( i=1; i<argc; i++ ) {
if( stat(argv[i],&statbuf) == 0 ) {
printf("%s\n",argv[i]);
}
}
}
이 모든 작업과 필요한 작업은 명령줄 인수를 통해 실행하고 유효한 파일(즉, stat()이 성공하는 파일)에 해당하는 문자열을 에코하는 것입니다.
물론, 똑같이 간단한 Python, Perl 또는 stat를 실행하는 셸 함수를 사용하여 이를 에뮬레이트할 수 있지만 C로 작성하면 실행 속도가 훨씬 빨라집니다.
ls 해킹에 관해서는 내 개인 위키에 다음과 같은 내용을 올렸습니다.http://linux.chalisque.net/LsIgnoreMissing
답변4
@DopeGhoti의 댓글이 저에게 도움이 되었습니다.
즉, 다음과 같이 연산자를 /dev/null
사용하여 오류를 리디렉션합니다 .2>
ls ./foldername/*.{a,b,}test 2> /dev/null