
다음을 수행하는 모든 디렉토리를 나열하려면 어떻게 해야 합니까?~ 아니다내부에 주어진 파일 이름을 가진 파일이 있습니까? 예를 들어 이 트리가 주어졌을 때
/
/a
README
file001
file002
/b
README
file001
/c
file003
나는 그 일을 하는 디렉토리를 나열하고 싶다.~ 아니다라는 파일이 있습니다 README
. 이 경우에는 디렉토리가 됩니다 /c
. 어떻게 해야 합니까? 예를 들어 어떤 구문도 생각할 수 없습니다 find
.
답변1
인수에 포함된 값 을 허용하는 find
GNU와 같은 구현을 가정하면 다음과 같습니다 .find
{}
-exec
$ find . -type d \! -exec test -e '{}/README' \; -print
또는 문제가 있는 삽입 없이:
$ find . -type d ! -exec sh -c 'test -e "$1"/README' sh {} \; -print
예
여기서 1/1부터 5/5까지의 디렉토리에는 README가 있고 다른 디렉토리는 비어 있습니다.
$ tree
.
|-- 1
| `-- 1
| `-- README
|-- 10
| `-- 10
|-- 2
| `-- 2
| `-- README
|-- 3
| `-- 3
| `-- README
|-- 4
| `-- 4
| `-- README
|-- 5
| `-- 5
| `-- README
|-- 6
| `-- 6
|-- 7
| `-- 7
|-- 8
| `-- 8
`-- 9
`-- 9
이제 이 버전의 명령을 실행하면 다음과 같습니다 find
.
$ find . -type d \! -exec test -e '{}/README' \; -print
.
./10
./10/10
./7
./7/7
./9
./9/9
./6
./6/6
./5
./8
./8/8
./4
./1
./3
./2
참고자료
답변2
. find
그냥 쉘을 사용하세요:
for d in */; do [ -f "$d"README ] || printf '%s\n' "$d"; done
c/
재귀적이어야 하는 경우 다음을 사용할 수 있습니다( 의 경우 bash
기본적 zsh
으로 이 작업을 수행할 수 있으며 set -o globstar
in 에서 사용 ksh93
).
shopt -s globstar
for d in **/; do [ -f "$d"README ] || printf '%s\n' "$d"; done
(도트 파일은 기본적으로 제외됩니다.)
답변3
-exec
옵션을 사용하여 find
파일을 확인한 다음 확인에 실패한 모든 결과를 인쇄 할 수 있습니다 .
find /path/to/base -mindepth 1 -maxdepth 1 -type d -exec test -e {}/README \; -o -print
답변4
이식 가능한 방법은 다음과 같습니다.
find . -type d -exec sh -c '
for dir do
[ -f "$dir/README" ] || printf "%s\n" "$dir"
done' sh '{}' +
[ -f file ]
파일이 있는지 테스트존재한다 그리고일반 파일인 것으로 확인되었습니다(심볼릭 링크 확인 후).
유형에 관계없이 해당 디렉토리의 항목으로만 존재하는지 테스트하려면 다음이 필요합니다. [ -e file ] || [ -L file ]
단, 해당 테스트를 수행하려면 디렉토리에 대한 검색 권한이 필요합니다. [ -x "$dir" ]
다음과 같은 경우를 설명하기 위해 몇 가지 테스트를 추가할 수 있습니다 .
find . -type d -exec sh -c '
for dir do
if [ -x "$dir" ]; then
[ -f "$dir/README" ] || printf "%s\n" "$dir"
else
printf >&2 "Cannot tell for \"%s\"\n" "$dir"
fi
done' sh '{}' +
또는 경쟁 조건을 피하려면 다음을 사용하십시오 zsh
.
find . -type d -exec zsh -c '
zmodload zsh/system
for dir do
ERRNO=0
if [ ! -f "$dir/README" ]; then
if [ "$errnos[ERRNO]" = ENOENT ]; then
printf "%s\n" "$dir"
else
syserror -p "ERROR: $dir/README: "
fi
fi
done' zsh '{}' +
또한보십시오Bash에 일반 파일이 없는지 어떻게 알 수 있나요?그래서.