![스크립트를 실행하기 위해 패턴과 일치하는 파일이 있는지 테스트하십시오.](https://linux55.com/image/32910/%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A5%BC%20%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%B4%20%ED%8C%A8%ED%84%B4%EA%B3%BC%20%EC%9D%BC%EC%B9%98%ED%95%98%EB%8A%94%20%ED%8C%8C%EC%9D%BC%EC%9D%B4%20%EC%9E%88%EB%8A%94%EC%A7%80%20%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%95%98%EC%8B%AD%EC%8B%9C%EC%98%A4..png)
if
특정 패턴과 일치하는 파일이 있는지 테스트하는 명령문을 작성하려고 합니다 . 디렉터리에 텍스트 파일이 있으면 지정된 스크립트를 실행해야 합니다.
내 현재 코드:
if [ -f /*.txt ]; then ./script fi
.txt
몇 가지 아이디어를 주십시오. 디렉토리에 있는 경우 에만 스크립트를 실행하고 싶습니다 .
답변1
[ -f /*.txt ]
존재하는 경우에만 true를 반환합니다.하나/
(그리고 단 하나의) 이름이 로 끝나고 .txt
일반 파일이거나 일반 파일에 대한 심볼릭 링크인 숨김되지 않은 파일 입니다.
[
이는 와일드카드가 명령(여기 ) 에 전달되기 전에 쉘에 의해 확장되기 때문입니다 .
/a.txt
따라서 and 가 있으면 /b.txt
, , and 5 개의 [
매개변수가 전달됩니다. 그러면 너무 많은 매개변수가 주어졌다고 불평할 것입니다.[
-f
/a.txt
/b.txt
]
[
-f
*.txt
패턴이 하나 이상의 숨겨지지 않은 파일(일반 또는 비정규)로 확장되는지 확인하려면 bash
셸에서 다음을 수행합니다.
shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
./script "$@" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"
shopt -s nullglob
구체적 이지만 bash
( shopt
예, nullglob
실제로는 에서 유래 zsh
), , , 와 같은 쉘에는 ksh93
동일한 zsh
명령문 yash
이 tcsh
있습니다.
그리고 zsh
, 테스트는패턴과 일치하는 파일이 있나요?이는 익명 함수와 N
(for nullglob
) 및 Y1
(첫 번째 조회 후 중지) glob 한정자를 사용하여 작성할 수 있습니다.
if ()(($#)) *.txt(NY1); then
do-something
fi
이러한 파일은 디렉터리의 내용을 읽어 이러한 파일을 찾으며 파일에 전혀 액세스하려고 시도하지 않으므로 쉘 계산 파일 목록 ls
과 같은 명령을 호출하는 것보다 더 효율적인 솔루션이 됩니다.stat
표준에 sh
해당하는 것은 다음과 같습니다.
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
문제는 Bourne 또는 POSIX 쉘의 경우 패턴이 일치하지 않으면 자체적으로 확장된다는 것입니다. 그래서 *.txt
으로 확장 하면 디렉토리에 파일이 없어서 *.txt
인지 .txt
, 아니면 *.txt
. 사용하면 [*].txt *.txt
둘을 구별할 수 있습니다.
*.txt
이제 적어도 하나와 일치하는지 확인하려면정기적인파일 또는 일반 파일에 대한 심볼릭 링크(제안한 대로 [ -f *.txt ]
) 또는 일치하는 모든 파일 *.txt
이정기적인파일(심볼릭 링크 해결 후)은 또 다른 이야기입니다.
그리고 zsh
:
if ()(($#)) *.txt(NY1-.); then
echo "there is at least one regular .txt file"
fi
if ()(($#)) *.txt(NY1^-.); then
echo "there is at least one non-regular .txt files"
fi
( -
심볼릭 링크가 해결되기 전에 테스트하려면 제거하십시오. 즉, 심볼릭 링크가 일반 파일을 가리키는지 여부에 관계없이 비정규 파일로 처리하십시오.)
답변2
가능한 해결책은 Bash 내장 입니다 compgen
. 이 명령은 일치하는 파일이 있는지 여부를 나타내는 종료 코드와 함께 와일드카드 패턴과 일치하는 모든 항목을 반환합니다.
compgen -G "/*.text" > /dev/null && ./script
더 빠른 솔루션을 찾는 동안 이 질문을 발견했습니다.
답변3
언제든지 다음을 사용할 수 있습니다 find
.
find . -maxdepth 1 -type f -name "*.txt" 2>/dev/null | grep -q . && ./script
설명하다:
답변4
Chazelas가 지적했듯이 와일드카드 확장이 두 개 이상의 파일과 일치하면 스크립트가 실패합니다.
그러나 나는 트릭을 사용했습니다 (내가 별로 좋아하지 않더라도) 우회:
PATTERN=(/*.txt)
if [ -f ${PATTERN[0]} ]; then
...
fi
어떻게 작동하나요?
와일드카드 확장은 파일 이름 배열과 일치하며 파일 이름이 있으면 첫 번째 파일 이름을 가져오고 일치 항목이 없으면 null을 가져옵니다.