아래와 같이 각 디렉토리에 텍스트 파일이 있는 두 개의 디렉토리를 생성한다고 가정합니다.
mkdir "Directory1"
mkdir "Directory2"
touch "Directory1/fileclass1_"{1..5}".txt"
touch "Directory1/fileclass2_"{1..5}".txt"
touch "Directory2/fileclass1_"{1..5}".txt"
touch "Directory2/fileclass2_"{1..5}".txt"
다음을 수행하여 모든 파일이 내부에 있는지 확인한다고 가정해 보겠습니다.
A=( "Directory1" "Directory2" )
B=( "fileclass1" "fileclass2" )
for a in "${A[@]}"; do
for b in "${B[@]}"; do
for i in {1..5}; do
name="${a}/${b}*${i}.txt"
[[ ! -e $name ]] && echo "$name Does Not Exist"
done
done
done
이 반환
Directory1/fileclass1*1.txt Does Not Exist
Directory1/fileclass1*2.txt Does Not Exist
...
그러나 이중 괄호를 단일 괄호로 바꾸면 다음과 같은 결과가 나옵니다.
A=( "Directory1" "Directory2" )
B=( "fileclass1" "fileclass2" )
for a in "${A[@]}"; do
for b in "${B[@]}"; do
for i in {1..5}; do
name="${a}/${b}*${i}.txt"
[ ! -e $name ] && echo "$name Does Not Exist"
done
done
done
아무것도 반환하지 않으며 이는 모든 파일이 실제로 거기에 있음을 나타냅니다.
이 경우 이중 괄호는 실패하지만 단일 괄호는 작동하는 이유는 무엇입니까? 나는 항상 이중 괄호를 사용해야 한다고 가정합니다. 문자열 일치의 와일드카드가 내가 가져서는 안 되는 것을 생성합니까?
답변1
조건부 -e
연산자는 특정 이름의 파일이 존재하는지 테스트합니다. 패턴 일치를 수행하지 않습니다. 와일드카드 패턴과 일치하는 파일이 하나 이상 있는지 테스트하는 대신 이름에 별표가 있는 파일이 존재하는지 [[ -e fileclass1*1.txt ]]
테스트합니다 .fileclass1*1.txt
fileclass1*1.txt
단일 괄호의 경우 인용되지 않았 [ ! -e $name ]
으므로 $name
값은 name
와일드카드 대체 및 토큰화를 거칩니다. name
값이 인 경우 Directory1/fileclass1*1.txt
와일드카드 패턴과 일치하는 파일 수에 따라 효과가 달라집니다.
- 패턴이 어떤 파일과도 일치하지 않으면 확장되지 않습니다. 그런 다음 운영자는
-e
파일 이름이Directory1/fileclass1*1.txt
존재하지 않는다는 것을 확인하므로[ ! -e $name ]
이는 사실입니다. - 패턴이 단일 파일과 일치하는 경우 해당 파일의 이름으로 대체됩니다. 그런 다음 운영자는
-e
파일 이름이 존재한다는 것을 확인하므로[ ! -e $name ]
false입니다. - 패턴이 두 개 이상의 파일과 일치하는 경우 일치하는 파일 이름 목록으로 대체되며, 이로 인해 조건에서 구문 오류가 발생합니다. 이 경우
[ ! -e $name ]
오류 메시지가 표시되고 실패 상태가 반환됩니다.
특수 구문( 그러나 [[ -e $name ]]
때문에 효과가 다릅니다 . 단어 분할이나 와일드카드 확장은 내부적으로 수행되지 않습니다 .[[ … ]]
[
[[ … ]]
실제 문제를 해결하려면 다음을 참조하세요.스크립트를 실행하기 위해 패턴과 일치하는 파일이 있는지 테스트하십시오.
1 경쟁 조건이 발생하는 경우를 제외하고 파일은 쉘이 와일드카드 패턴을 확장하기 위해 디렉토리 내용을 나열하는 시간과 운영자가 파일이 존재하는지 확인하는 시간 사이에 삭제됩니다 .-e