(이것은 복잡한 환경에서 가장 간단한 작업 예입니다.)
d
파일이 포함된 디렉토리 가 있습니다 1.txt 2.txt 3.txt 4.wav
. 내 현재 디렉토리는 다른 곳에 있습니다.
ls d
보고 1.txt 2.txt 3.txt 4.wav
하십시오.
하지만 그게 내가 원하는 전부이기 1.txt 2.txt 3.txt
때문에 노력합니다 ls d/*.txt
.
그러나 이것은 쉘이 파일을 보기 전에 확장하기 때문에 d/
모든 파일 이름 앞에 다음이 추가됩니다 .d/1.txt d/2.txt d/3.txt
*
ls
내가 원하는 것을 얻으려면 , 대안으로 새 쉘을 생성 1.txt 2.txt 3.txt
할 수도 있습니다 . 출력을 필터링하는 더 나은 방법, 덜 투박하고 함정과 엣지 케이스에 덜 취약한 방법이 있습니까 ?ls d | grep txt
ls d/*.txt | xargs basename -a
(cd d; ls *.txt)
ls
답변1
그리고 zsh
:
printf '%s\n' d/*.txt(:t)
:t
csh 기록 수정자와 유사하지만 glob 한정자에서는 다음을 얻을 수 있습니다.꼬리파일 이름.
반품:
files=(d/*.txt)
printf '%s\n' $files:t
Bourne과 유사한 다른 쉘에서는 언제든지 다음을 수행할 수 있습니다.
(cd d && printf '%s\n' *.txt)
새 셸을 포크하는 것이 아니라 하위 셸 환경을 생성한다는 점에 유의하세요. 대부분의 쉘 구현에서 하위 쉘 환경은 하위 프로세스를 포크하여 달성되지만 새 쉘은 그 안에서 실행되지 않습니다(새 쉘이 아니지만 새 프로세스에서 동일한 쉘이 포크됨). 또한 하위 셸의 마지막 명령이 외부 명령인 경우 대부분의 셸(은 아니지만 bash
)은 추가 프로세스를 생성하지 않으므로 실행 중인 총 프로세스 수는 하위 셸 환경이 없을 때와 동일합니다.
ksh93
서브쉘을 포크하지 않습니다. 서브쉘을 종료할 때 서브쉘에서 수행된 수정 사항을 실행 취소하여 이를 수행합니다. 따라서 ( printf
내장되어 있는 경우) (cd d && printf '%s\n' *.txt)
추가 프로세스가 분기되지 않습니다 .
또한 ls
파일과콘텐츠인수로 전달되는 디렉토리입니다. 여기에서 ls
쉘에서 제공한 이름만 인쇄하려는 경우에는 필요하지 않지만 고집하는 경우 ls
해당 -d
옵션을 전달하여 디렉터리의 내용을 나열하지 않도록 해야 합니다.
(cd d && ls -d -- *.txt)
답변2
귀하가 요청한 것을 수행하는 가장 쉬운 방법은 다음과 같습니다.
$ ( cd d; ls *.txt )
1.txt 2.txt 3.txt
이는 서브셸 내에서 발생하므로 ( ... )
디렉터리 변경은 영구적이지 않으며 이 두 명령을 실행하는 경우에만 유효합니다.
더 강력한 버전은 다음과 같습니다.
$ ( cd d && ls -d -- *.txt )
1.txt 2.txt 3.txt
ls
디렉토리 변경이 성공 하지 않으면 그 안의 내용은 실행되지 않고 ls
디렉토리 내용 대신 나열되며 이름이 대시로 시작하는 파일은 옵션으로 제공되지 않습니다.
위치 매개변수( 등) $1
를 변경해도 괜찮다면 이 방법도 비교적 간단합니다.$2
$ set d/*.txt
$ for f do printf '%s\n' "${f#d/}"; done
1.txt
2.txt
3.txt
이는 POSIX 셸에서 작동합니다.
$ dash -c 'set d/*.txt; for f do printf "%s\n" "${f#d/}"; done'
1.txt
2.txt
3.txt
GNU find를 사용할 수 있습니다 -printf
.
$ find d -maxdepth 1 -iname "*.txt" -printf "%f\n" | sort
1.txt
2.txt
3.txt
그러나 이것은 충분히 복잡해졌습니다. 죄송합니다. 제가 아는 한 더 이상 "쉬운" 해결책은 없습니다.