폴더가 있는지 확인하고 폴더가 있으면 한 가지 작업을 수행하고 없으면 다른 작업을 수행해야 합니다. 이 작업을 수행하기 위해 find를 사용하지만 올바른 방법을 찾을 수 없습니다.
find /path/to/destination -maxdepth 1 -type d -name "dir*" -exec bash -c '[[ $1 ]] && echo ok || echo "not ok"' _ {} \;
그러나 bash 부분의 부분은 구현하기에 더 새로운 것입니다. 제안 사항이 있습니까?
답변1
이 작업은 이전 조건 (and)과 일치하는 파일에 대해서만 수행 되며 -exec
파일당 한 번 수행됩니다.-name 'dir*'
-type d
여기에서 다음과 같은 작업을 수행할 수 있습니다 zsh
.
dirs=(/path/to/destination/dir*(N/))
if (($#dirs)); then
echo Found these dirs:
printf ' - %s\n' $dirs
else
echo >&2 No dir found
fi
또는 bash 버전 4.4 이상 및 find
호환 가능한 GNU를 사용하는 경우( -maxdepth
사용 시 이미 GNU 확장을 사용하고 있어야 함):
readarray -td '' dirs < <(
find /path/to/destination -maxdepth 1 -type d -name "dir*" -print0)
if ((${#dirs[@]})); then
echo Found these dirs:
printf ' - %s\n' "${dirs[@]}"
else
echo >&2 No dir found
fi
답변2
해당 이름 패턴과 일치하는 디렉터리가 있는지 확인하려면 find
해당 디렉터리에 대한 더미 출력을 인쇄하고 출력이 비어 있는지 확인할 수 있습니다. 예를 들어:
if [[ "$(find -type d -name "dir*" -printf .)" ]] ; then
echo "some matching directory exists"
else
echo "no matching directory exists"
fi
에 find
전달할 수도 있습니다 . 명령이 출력을 생성하지 않으면 문제가 없습니다.-exec bash -c '...' _ {} \;
-printf
시작된 명령의 출력을 캡처하고 이를 가상 출력과 분리해야 하는 경우 find
상황은 더욱 악화됩니다 . 임시 파일이나 리디렉션 트릭이 필요합니다. 이는 somecmd
일치하는 모든 디렉터리에서 실행되어야 하며 find
실행 출력을 somecmd
스크립트 stdout으로 보낸 다음 일치하는 항목이 있는지 알려주어야 합니다.
exec 3>&1
any=$(find -type d -name "dir*" -printf . -exec bash -c 'somecmd "$1" >&3' _ {} \; )
if [[ "$any" ]] ; then
echo "matching directories were processed"
else
echo "no matching directory exists"
fi
exec 3>&-
물론 명령이 내려지면find
언제나출력을 생성하며 더미 출력이 필요하지 않습니다. 인쇄물 을 캡처하여 find
비어 있는지 확인하세요.
답변3
추악하지만 bash에서는 다음과 같습니다.
(shopt -s nullglob; if ! [ -z /path/to/destination/dir*/ ] 2>&-; then echo ok; else echo not ok; fi)
활성화되면 nullglob
다음 /path/to/destination/dir*/
으로 확장됩니다.
- 일치하는 디렉터리가 없으면 아무 작업도 수행하지 않습니다. 이 경우 테스트는
-z
성공하므로 부정적인 테스트는 실패합니다. 또는 일치하는 모든 디렉터리 목록입니다. 이 경우:
- 디렉터리가 하나만 있으면
-z
테스트가 실패합니다. -z
하나의 피연산자만 필요하기 때문에 디렉터리가 여러 개 있는 경우 테스트 명령이 실패합니다.
따라서 부정적인 테스트가 통과됩니다.
- 디렉터리가 하나만 있으면
예:
$ if ! [ -z /a* ] 2>&-; then echo ok; else echo not ok; fi
not ok
$ if ! [ -z /b* ] 2>&-; then echo ok; else echo not ok; fi # multiple: /bin /boot
ok
$ if ! [ -z /h* ] 2>&-; then echo ok; else echo not ok; fi # single: /home
ok
.[[ ... ]]