나는 현재 다음과 같이 디렉토리를 검색하고 특정 파일을 포함하지 않는 디렉토리를 나열하는 방법을 알고 있습니다.
find parent_directory -mindepth 1 -maxdepth 1 -type d '!' -exec sh -c 'ls -1 "{}"|egrep -i -q "^file_name$"' \; -print
하지만 이제 결과 디렉토리를 사용하여 다른 파일이 포함되어 있는지 확인하고 싶지만 확장된 단일 행 표현식에서는 이를 수행할 수 없습니다. 이것이 가능한가?
답변1
다음을 통해 필요한 디렉터리를 결정할 수도 있습니다.
find . -maxdepth 2 -path '*/*/wanted.txt' -type f \
-execdir test ! -f unwanted.txt \; -execdir pwd \;
작동 방식은 다음과 같습니다.
- 깊이가 2인 항목을 찾습니다.
- 2개의 슬래시가 있으므로 이
-path
옵션은 깊이를 2로 제한합니다. 최대 깊이는 추가 진행을 방지하고 2개의 명시적 슬래시는 깊이가 2 미만을 방지하기 때문입니다. - 깊이 수준 2에서 발견된 Wanted.txt 항목은 일반 파일인 것이 바람직하며 다음을 통해 보장됩니다.
-type f
- 이
-execdir
옵션은 Wanted.txt가 있는 디렉터리로 작업을 승격시켜test
명령이 원하지 않는 파일을 찾습니다. -execdir
다음으로, 원치 않는 파일이 발견되지 않은(승격된 대로) 디렉토리를 인쇄하는 간단한 문제입니다.- 이에 대해 자세히 설명하지 않고 디렉토리는 특정 파일을 한 번만 포함할 수 있으므로
-execdir
작업은 /directory에서 한 번 실행되고 최소한 일반 파일 Wanted.txt를 포함하는 것이 확실한 디렉토리에서만 실행됩니다.
답변2
하위 디렉터리로 재귀적으로 이동하고 싶지 않은 것 같으므로 특정 파일이 없는 디렉터리를 찾는 데 필요한 것은 다음과 같습니다.
for dir in */; do [ ! -e "$dir"/"$filename" ] || printf '%s\n' "$dir"; done
그리고 그 중 실제로 다른 파일이 있는 파일을 확인하려면 다음을 수행하세요.
for dir in */; do
[ ! -e "$dir"/"$filename1" ] &&
[ -e "$dir"/"$filename2" ] &&
printf '%s\n' "$dir";
done
또는 약간 더 명확한 구문을 사용하면 다음과 같습니다.
for dir in */; do
if [ ! -e "$dir"/"$filename1" ]; then
if [ -e "$dir"/"$filename2" ]; then
printf '%s\n' "$dir";
fi
fi
done
이 모든 작업은 셸에 내장된 도구를 사용하여 수행됩니다. 구체적으로:
[
: 이것과 그에 수반되는 것들은]
내장 함수의 동의어입니다test
( sh 스타일 쉘을 사용하는 경우help [
또는 참조).help test
이는 셸에서 테스트 작업을 작성하는 방법입니다.-e
: 파일/디렉토리 등이 존재하는지 테스트합니다. 바라보다help test
. 간단한 형식은[ -e file ]
존재하는 경우 true를 반환하는 것입니다.file
[ ! -e filename ]
:!
테스트를 거꾸로 하면 됩니다. 그렇다면 그것은[ ! -e file ]
사실이다file
아니요존재하다.
전체적으로 이는 위 명령이 다음을 수행함을 의미합니다.
## Iterate over every directory (dirs only because of the '/' in '*/')
## saving each of them in the variable $dir.
for dir in */; do
## If this $dir does not contain $filename1
if [ ! -e "$dir"/"$filename1" ]; then
## If this $dir does contain $filename2
if [ -e "$dir"/"$filename2" ]; then
## Print the directory name
printf '%s\n' "$dir";
fi
fi
done
물론, 실행하려면 먼저 $filename1
적절하게 설정 해야 합니다 $filename2
. 예를 들어:
filename1="unwantedFile"
filename2="wantedFile"
답변3
파일 이외의 zsh
파일이 포함된 현재 디렉토리의 디렉토리를 나열하려면 , 를 사용하십시오 .musthave
mustnothave
contain() [[ -e $REPLY/$1 || -L $REPLY/$1 ]]
printf '%s\n' *(D/e(contain musthave)^e(contain mustnothave))
다음을 수행하십시오.
find ... -exec sh -c 'ls {}' \;
이식성이 없을 뿐만 아니라 명령 주입 취약점이기도 합니다. 예를 들어, $(reboot)
또는이라는 디렉터리가 있으면 ;reboot
또는 명령줄 ls $(reboot)
이 ls ;reboot
실행되어 재부팅됩니다. {}
코드 매개변수(또는 다른 언어)에 포함되어서는 안 됩니다. sh
그렇지 않으면 오해될 수 있습니다. 사용:
find ... -exec sh -c 'ls "$1"' sh {} \;
대신에.