다음과 같은 디렉토리 구조가 있습니다. 이름이 지정된 파일이 있는 디렉터리를 찾아 log.xml
특정 심볼릭 링크가 가리키는 디렉터리를 제외한 모든 디렉터리를 완전히 삭제해야 합니다.
예를 들어, /dir1/main/app1/v004/
및 /dir1/main/app2/v004/log.xml
기호 링크로 지정되므로 삭제하면 안 됩니다.
또한 심볼릭 링크가 가리키는 디렉토리 이외의 디렉토리를 찾지 않고 어떻게 삭제합니까 log.xml
?
올바른 솔루션을 제공하는 데 도움을 주실 수 있나요?
/dir1/main/app1/v001/
/dir1/main/app1/v002/log.xml
/dir1/main/app1/v003/log.xml
/dir1/main/app1/v004/log.xml
/dir1/main/app1/v005/log.xml
/dir1/ln1/app -> /dir1/main/app2/v004
/dir1/main/app2/v001/
/dir1/main/app2/v002/log.xml
/dir1/main/app2/v003/log.xml
/dir1/main/app2/v004/log.xml
/dir1/main/app2/v005/log.xml
/dir1/ln2/app -> /dir1/main/app2/v004
답변1
app
v001
(제외 log.xml
) 및 v004
(심볼릭 링크로 가리키는)을 제외하고 디렉터리의 모든 하위 디렉터리를 삭제한다고 가정합니다 .
for topdir in /dir1 /dir2; do
for dirpath in "$topdir"/main/app/*/; do
if [ -e "$dirpath/log.xml" ] && ! [ "$dirpath" -ef "$topdir"/ln/app ]
then
printf 'Would remove "%s"\n' "$dirpath"
# rm -rf "$dirpath"
fi
done
done
외부 루프는 두 개의 최상위 디렉터리를 반복하는 데 사용됩니다 /dir1
( 이를 글로빙 패턴으로 사용할 /dir2
수 있음 ). /dir[12]
최상위 디렉토리의 이름이 topdir
변수에 저장됩니다.
내부 루프는 아래 하위 디렉터리를 통해 반복 app
됩니다 $topdir
. 하위 디렉터리에 이름이 지정된 항목 log.xml
(첫 번째 테스트, with )이 포함되어 있고 심볼릭 링크가 해당 디렉터리 (두 번째 테스트, with ) -e
를 가리키지 않는 경우 해당 디렉터리를 삭제할 수 있습니다."$topdir"/ln/app
-ef
이 -e
테스트는 주어진 경로 이름의 존재 여부에 대한 표준 테스트입니다. 이 -ef
테스트는 비표준이지만 bash
쉘에 의해 구현되며 기호 링크를 확인한 후 두 경로 이름이 동일한 파일(또는 이 경우 디렉토리)을 참조하는지 여부를 테스트합니다.
실제 삭제 내용은 안전을 위해 주석 처리되어 있습니다. 이 명령을 활성화하기 전에 이전에 백업한 데이터에 대해 테스트해야 합니다 rm
.
라는 콘텐츠가 포함되어 있는지 여부에 관계없이 하위 디렉터리를 제거하려면 명령문이 다음과 같이 보이 도록 테스트를 log.xml
제거하십시오.-e
if
if ! [ "$dirpath" -ef "$topdir"/ln/app ]; then
printf 'Would remove "%s"\n' "$dirpath"
# rm -rf "$dirpath"
fi
답변2
GNU find
에는 옵션이 있습니다 -samefile
. 이를 작동시키려면 -L 옵션을 포함해야 합니다.
다음 두 명령의 출력을 살펴보십시오.
(cd /dir1 ; find -L . -samefile ln/app ) # your file and link
(cd /dir1 ; find -L . -not -samefile ln/app ) # everything other than your file and link
두 번째는 삭제하려는 파일 목록을 생성해야 합니다. 디렉토리가 아닌 파일만 나열하고 싶을 수도 있습니다. 그렇다면 다음을 추가하세요.-type f
find -L . -type f -samefile ln/app)
파일을 삭제하는 것은 find 명령에 exec 작업을 추가하는 것만큼 간단합니다. 예를 들어-exec rm -v {} \;