Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python으로 유닉스 경로 단순화하기: 정규 경로(Canonical Path) 변환 완벽 가이드

유닉스 파일 시스템 스타일의 파일 절대 경로가 주어졌을 때, 이를 단순화해야 하는 경우가 있습니다. 다시 말해 주어진 경로를 정규 경로(canonical path)로 변환하는 작업입니다.

유닉스 스타일 파일 시스템에서는 마침표 하나('.')가 현재 디렉터리를 의미하며, 마침표 두 개('..')는 한 단계 위 디렉터리(부모 디렉터리)로 이동함을 나타냅니다.

정규 경로의 속성

  • 경로는 항상 슬래시 /로 시작해야 합니다.
  • 두 디렉터리 이름 사이에는 슬래시 /가 정확히 하나만 존재해야 합니다.
  • 마지막 디렉터리 이름이 있는 경우, 그 뒤에 슬래시 /가 붙어서는 안 됩니다.
  • 정규 경로는 해당 절대 경로를 표현하는 가장 짧은 문자열이어야 합니다.

변환 예시

예를 들어 다음과 같은 입력 경로가 주어졌다고 가정해 보겠습니다.

  • "/home/""/home"
  • "/../""/"
  • "/home//user/""/home/user"

해결 알고리즘

이 문제는 스택(stack) 개념을 활용하면 깔끔하게 해결할 수 있습니다. 처리 순서는 다음과 같습니다.

  1. 리스트 st를 생성하고 초기값으로 '/'를 넣습니다.
  2. 주어진 경로를 구분자 '/'로 분할한 문자열 리스트를 a에 저장합니다.
  3. a의 각 요소 i에 대해 다음을 수행합니다.
    • i'..'인 경우: st의 길이가 1보다 크면 마지막 요소를 제거하고, 그렇지 않으면 건너뜁니다.
    • i'.'인 경우: 아무 작업 없이 건너뜁니다.
    • i가 빈 문자열이 아닌 경우: '/' + ist에 추가합니다.
  4. st에 요소가 하나뿐이라면 '/'를 반환합니다.
  5. st의 모든 요소를 이어 붙여 최종 경로를 반환합니다.

Python 구현 예제

class Solution:
    def simplifyPath(self, a):
        st = ['/']
        a = a.split("/")
        for i in a:
            if i == '..':
                if len(st) > 1:
                    st.pop()
                else:
                    continue
            elif i == '.':
                continue
            elif i != '':
                st.append("/" + str(i))
        if len(st) == 1:
            return "/"
        return "".join(st[1:])

ob1 = Solution()
print(ob1.simplifyPath("/home/"))
print(ob1.simplifyPath("/../"))
print(ob1.simplifyPath("/home//user/"))

입력

"/home/"
"/../"
"/home//user/"

출력

/home
/
/home/user

동작 원리 정리

경로를 '/' 기준으로 분할하면 빈 문자열, '.', '..', 실제 디렉터리 이름 등이 섞인 리스트가 만들어집니다. 여기서 의미 없는 요소들을 걸러내고, '..'가 나타날 때는 스택에서 마지막 디렉터리를 꺼내는 방식으로 부모 디렉터리 이동을 처리합니다. 이 과정을 거치면 중복 슬래시와 불필요한 상대 참조가 모두 제거된, 가장 짧고 표준적인 형태의 절대 경로를 얻을 수 있습니다.