절대 경로를 단축


17

때로는 현재 작업 디렉토리를 참조로 사용하여 Linux 도구에 대한 명령 행 매개 변수와 같은 긴 절대 경로를 단축 할 수 있습니다.

$ pwd
/home/heh

$ cat /home/heh/mydir/myfile
my stuff

$ cat mydir/myfile
my stuff

이 도전에서는 두 가지 매개 변수를받는 함수 나 프로그램을 만들어야합니다.

  1. Linux 형식을 사용하는 절대 경로 (로 시작 /)
  2. 동일한 형식을 사용하는 현재 디렉토리

출력은 다음 중 더 짧습니다.

  • 입력 1은 변경되지 않았습니다
  • 절대 경로와 동일한 파일 / 디렉토리를 참조하는 상대 경로

좋은 점 :

  • 운영 체제가 Linux와 호환되는 경우 입력으로받는 대신 시스템의 현재 디렉토리를 사용할 수 있습니다
  • 입력에 영숫자 (및 경로 구분자) 만 포함되어 있다고 가정 할 수 있습니다.
  • 입력 절대 경로 /끝에 경로 구분 기호가 없다고 가정 할 수 있습니다
  • 입력 현재 디렉토리 /끝에 경로 구분 기호가 있다고 가정 할 수 있습니다
  • 절대 경로가 기존 파일을 참조하거나 파일의 일부가 액세스 가능한 디렉토리라고 가정 할 수 없습니다. 그러나 현재 디렉토리는 유효하다고 가정 할 수 있습니다.
  • 어느 경로 근처에도 심볼릭 링크가 없다고 가정 할 수 있습니다-심볼릭 링크를 다루는 특별한 방법이 필요하지 않기 때문에
  • 입력 중 하나가 루트 디렉토리 인 경우를 지원할 필요가 없습니다.
  • "현재 디렉토리"는 다음과 같이 출력되어야합니다 .(빈 문자열은 유효하지 않습니다)

테스트 사례 (입력 1, 입력 2, 출력) :

/home/user/mydir/myfile
/home/user
mydir/myfile

/var/users/admin/secret/passwd
/var/users/joe/hack
../../admin/secret/passwd

/home/user/myfile
/tmp/someplace
/home/user/myfile

/dir1/dir2
/dir1/dir2/dir3/dir4
../..

/dir1/dir2
/dir1/dir2
.

1
"입력 현재 디렉토리 /끝에 경로 구분 기호가 있다고 가정 할 수 있습니다 ." 그러나 귀하의 예에서는 그렇지 않습니다.
Shaggy

1
나는 이런 식으로 좋아하지만 어떤 사람들은 다른 식으로 그것을 좋아합니다
anatolyg


절대 경로와 상대 경로의 길이가 같은 경우 어떻게됩니까?
Dennis

1
이것은 몇 가지 중요한 테스트 케이스를 누락되었습니다 /home/test /home/user/mydir/myfile /home/test/a/b /a/b/d/e /a/b
나단 메릴

답변:


7

줄리아 0.5 , 32 바이트

!,~=relpath,endof
t->~t<~!t?t:!t

현재 작업 디렉토리를 기본으로 사용하며 현재 TIO에서 테스트 할 수 없습니다.

예제 실행

경고 : 파일 시스템이 변경됩니다.

$ sudo julia --quiet
julia> function test(target,base)
       mkpath(base)
       cd(base)
       shorten(target)
       end
test (generic function with 1 method)
julia> !,~=relpath,endof
(relpath,endof)

julia> shorten = t->~t<~!t?t:!t
(::#1) (generic function with 1 method)

julia> test("/home/user/mydir/myfile","/home/user")
"mydir/myfile"

julia> test("/var/users/admin/secret/passwd","/var/users/joe/hack")
"../../admin/secret/passwd"

julia> test("/home/user/myfile","/tmp/someplace")
"/home/user/myfile"

julia> test("/dir1/dir2","/dir1/dir2/dir3/dir4")
"../.."

julia> test("/dir1/dir2","/dir1/dir2")
"."

대체 버전, 35 바이트 (이진)

^,~=relpath,endof
t-b=~t<~t^b?t:t^b

기본 디렉토리를 입력으로 사용하므로 파일 시스템을 수정하지 않고 테스트 할 수 있습니다.

온라인으로 사용해보십시오!


Base.-명시 적으로 가져 오지 않는 한 재정의 오류?
Julian Wolf

0.5에서는 오류가 발생할 수 있지만 -재정의하기 전에 사용하는 경우에만 가능 합니다. 0.4에서는 재정의 전에 사용 여부를 경고합니다.
Dennis

9

자바 스크립트 (ES6) 107 106 바이트

카레 구문에서 절대 경로 a와 현재 경로 c를 사용합니다 (a)(c).

a=>c=>(A=a.split`/`,s='',c.split`/`.map(d=>!s&A[0]==d?A.shift():s+='../'),s+=A.join`/`)[a.length]?a:s||'.'

테스트 사례


와 함께 아주 좋은 트릭 [a.length]! Node.js 답변을 향상시키기 위해 빌릴 수 있습니까?
zeppelin

@zeppelin은 물론이다. 해봐!
Arnauld


5

ES6 (Node.js REPL), 56, 54, 46, 45 바이트

  • "."대신 빈 문자열을 사용하십시오. 현재 디렉토리 (입력시)를 나타 내기 위해 -1 바이트
  • 빌린 [f.length]Arnauld의 @에서 트릭을 대답 , -6 바이트
  • 명시 적 디렉토리 매개 변수 대신 현재 디렉토리를 사용하십시오 (-2 바이트).
  • 불필요한 괄호 제거 -2 바이트

골프

f=>(r=path.relative("",f))[f.length]?f:r||"."

테스트

> F=f=>(r=path.relative("",f))[f.length]?f:r||"."
[Function: F]

> F("/home/user/mydir/myfile")
'mydir/myfile'

> F("/var/users/admin/secret/passwd")
'../../admin/secret/passwd'

> F("/home/user/myfile")
'/home/user/myfile'

> F("/dir1/dir2")
'../..'

> F("/dir1/dir2")
'.'

node.js 함수를 허용하지 않습니까?
Downgoat

@ Downgoat Javascript 람다는 대답의 형태로 널리 받아 들여지기 때문에 Node.js가 다르게 처리되어야하는 이유를 알 수 없습니다.
zeppelin

4

파이썬 2, 135 144 바이트

i=0
a,c=input()
b,d=a.split('/')*(a!=c),c.split('/')
while b[:i+1]==d[:i+1]:i+=1
print'.'[i:]or min('/'.join(['..']*len(d[i:])+b[i:]),a,key=len)

온라인으로 사용해보십시오!

길지만 내장 경로 기능이없는 솔루션을 원했습니다.

편집 : Nathan Merrill이 제공 한 테스트 사례를 설명하기 위해 9 바이트 추가



2

파이썬 3 – 53 바이트

사용 os.path:

import os
lambda x:min(x,os.path.relpath(x),key=len)

전체 프로그램 (61 바이트) :

import os
x=input();print(min(x,os.path.relpath(x),key=len))

좋은 지적입니다. 파이썬은 지금 선두에 있습니다.
matsjoyce

@anatolyg Ha, 나는 적어도 하나의 테스트 사례를 놓칠 줄 알았습니다 ... 😒 All fixed now.
matsjoyce

1

PHP, 204 바이트

[,$l,$p]=$argv;$z=($d=array_diff_assoc)($y=($w=explode)("/",$p),$x=$w("/",$l));$m=str_pad("",3*count($z)-1,"../");$j=join("/",$r=$d($x,$y));echo$l!=$p?strlen($u=$m&&$j?"$m/$j":$m.$j)<strlen($l)?$u:$l:".";

테스트 케이스

넓히는

[,$l,$p]=$argv;
$z=($d=array_diff_assoc)($y=($w=explode)("/",$p),$x=$w("/",$l));
$m=str_pad("",3*count($z)-1,"../");
$j=join("/",$r=$d($x,$y));
echo$l!=$p
    ?strlen($u=$m&&$j?"$m/$j":$m.$j)<strlen($l)
      ?$u
      :$l
    :".";

../../대신 출력 of ../..이 허용되면 175 바이트로 단축 될 수 있습니다

[,$l,$p]=$argv;$z=($d=array_diff_assoc)($y=($w=explode)("/",$p),$x=$w("/",$l));echo$l!=$p?strlen($m=str_pad("",3*count($z),"../").join("/",$r=$d($x,$y)))<strlen($l)?$m:$l:".";

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.