파일을 반복하고 특정 이름 패턴을 가진 파일을 제외합니다. Shell

파일을 반복하고 특정 이름 패턴을 가진 파일을 제외합니다. Shell

현재 디렉터리의 파일을 반복하고 특정 이름 패턴을 가진 특정 파일을 제외하려면 어떻게 해야 합니까? 솔루션은 POSIX와 호환되어야 합니다.

제외할 파일이 test[0-9].txt 및 work-.*(정규식 사용) 패턴을 따른다고 가정합니다.

지금까지 내 코드는 다음과 같습니다.

for file in * 
do 
    if test "$file" != "test[0-9].txt" -o "$file" != "work-.*"
    then 
        echo "$file"
    fi 
done 

현재 출력은 작업 디렉터리의 모든 파일입니다. 테스트의 패턴 일치가 잘못된 것은 확실합니다. 그런데 어떻게 수정합니까?

답변1

if test "$file" != "test[0-9].txt" -o "$file" != "work-.*"

test유틸리티는 패턴 일치를 수행하지 않습니다. 이를 위해서는 Ksh/Bash/Zsh [[ ]]구성이 필요합니다(적어도 Bash에서는 모드를 참조할 필요가 없습니다). 그래서:

for file in *; do 
    if [[ "$file" != test[0-9].txt && "$file" != work-.* ]]; then 
        echo "$file"
    fi 
done 

hello.txt가 있는 경우 인쇄 하지만 test1.txt또는 은 인쇄하지 않습니다 work-.foo.

필요하신 점 참고해주세요그리고바꾸다또는거기에서 (x ≠ a또는x ≠ b)는 모든 x와 일치합니다.

바라보다:

엄격한 POSIX sh에서는 다음을 사용하여 패턴 일치를 수행해야 합니다 case.

for file in *; do 
    case $file in
        test[0-9].txt|work-.*) false;;
        *) echo "$file";;
    esac
done 

test(에 표시된 대로) 뒤에 여러 숫자를 일치시키려면 ksh 스타일 확장 glob 및 (그리고 모든 컨텍스트에서 작동하도록 하려면 Bash에서) test123.txt필요합니다 . Kusalananda가 지적한 것처럼 해당 경로로 가면 다음과 같은 작업도 수행할 수 있습니다.test+([0-9]).txtshopt -s extglob

for file in !(test[0-9].txt|work-.*); do
    echo "$file"
done

답변2

가능한 모든 조합을 사용하여 문자열을 만들 수 있습니다.

all=:
for thing in *test[0-9].txt work-.*; do
    all=$all$thing:
done
if [[ "$all" == *:"$file":* ]]; then
    # it is in the list

관련 정보