배열의 파일을 제외한 모든 파일 가져오기 - Bash

배열의 파일을 제외한 모든 파일 가져오기 - Bash

특정 디렉터리의 모든 파일(그러나 미리 정의된 목록의 파일 목록)에 대해 일부 작업을 수행하는 일회용 유틸리티를 작성해야 합니다. 주어진 목록은 미리 정의되어 있으므로 이를 배열로 하드코딩하겠습니다.

그렇다면 주어진 배열에 없는 모든 파일의 이름을 어떻게 얻을 수 있습니까? 이는 표준 Unix 스크립트(bash, awk, Perl)일 수 있습니다.

답변1

이를 통해 bash다음을 수행할 수 있습니다.

all=(*)
except=(file1 file2 notme.txt)
only=()
IFS=/
for file in "${all[@]}"; do
  case "/${except[*]}/" in
    (*"/$file/"*) ;;     # do nothing (exclude)
    (*) only+=("$file")  # add to the array
  esac
done
ls -ld -- "${only[@]}"

(이것은 현재 디렉터리의 파일에 대해 작동하지만 조회를 위해 배열 요소를 연결하는 all=(*/*) except=(foo/bar)데 사용하는 것과 같은 전역 변수에 대해서는 신뢰할 수 없습니다 /.)

"${array[*]}"이는 배열의 요소가 ( 파일에 나타나지 않기 때문에 $IFS여기에서 선택한 첫 번째 문자)와 연결 된다는 사실을 기반으로 합니다./이름; NUL은 파일에 나타날 수 없는 문자입니다., 그러나 불행하게도 bash(반대로 zsh변수에 그러한 문자를 가질 수는 없습니다). 따라서 그 안에 있는 각 파일에 대해 $all(여기에서는 $file존재를 foo예로 사용) 제외할지 case "/file1/file2/notme.txt/" in (*"/foo/"*)여부를 확인합니다 .$file

답변2

다음을 사용하는 것이 더 쉽습니다 zsh.

except=(file1 file2 notme.txt)
all=(*)
only=(${all:|except})
ls -ld -- $only

니모닉 ${all:|except}: 요소$all 술집그것들 $except.

$except파일이 다음 과 같이 배열에 있는지 확인할 수도 있습니다 .글로벌 예선:

ls -ld -- *.txt(^e:'((except[(Ie)$REPLY]))':)

또는 다음 기능을 사용하세요.

in_except() ((except[(Ie)${1-$REPLY}]))
ls -ld -- *.txt(^+in_except)

답변3

파일 이름이 충분히 간단하면 다음을 사용할 수 있습니다.배쉬 GLOBIGNORE변수:

GLOBIGNORE변수를 사용하여 패턴과 일치하는 파일 이름 세트를 제한할 수 있습니다. GLOBIGNORE설정된 경우 GLOBIGNORE이러한 패턴 중 하나와 일치하는 각 일치하는 파일 이름이 일치 목록에서 제거됩니다. 이 옵션을 설정 하면 대소문자에 관계없이 nocaseglobin의 패턴과 일치하는 항목을 검색합니다 . GLOBIGNORE설정되고 비어 있지 않으면 filename ...은 항상 무시됩니다. GLOBIGNORE그러나 GLOBIGNOREnull이 아닌 값으로 설정하면 dotglob쉘 옵션을 활성화하는 효과가 있으므로 ' '로 시작하는 다른 모든 파일 이름이 .일치합니다. ''로 시작하는 파일 이름을 무시하는 이전 동작을 얻으려면 .' .*'을(를) 설정하십시오. 이 옵션은 GLOBIGNORE설정되지 않은 경우 dotglob비활성화됩니다 .GLOBIGNORE

$ echo *
bin boot dev etc home lib lib64 lost+found mnt opt proc root run sbin srv sys tmp usr var
$ except=(etc lib lib64 tmp sbin)
$ GLOBIGNORE=$(IFS=:; printf "%s" "${except[*]}")
$ echo *
bin boot dev home lost+found mnt opt proc root run srv sys usr var

물론 배열을 생성하는 경우 변수를 직접 설정할 수 있습니다 GLOBIGNORE.

GLOBIGNORE=etc:lib:lib64:tmp:sbin

목록에 있을 수 있는 적절한 bash 와일드카드 패턴을 활용할 수도 있습니다.

GLOBIGNORE=etc:lib*:tmp:sbin

관련 정보