Mutlak bir yolu kısaltın


17

Bazen uzun bir mutlak yol, örneğin bir linux aracına yönelik bir komut satırı parametresinde, geçerli çalışma dizini başvuru olarak kullanılarak kısaltılabilir:

$ pwd
/home/heh

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

$ cat mydir/myfile
my stuff

Bu meydan okumada, iki parametre alan bir işlev veya program yapmalısınız:

  1. Linux formatını kullanarak mutlak yol (ile başlar /)
  2. Aynı dizini kullanarak geçerli dizin

Çıktı aşağıdakilerden daha kısadır:

  • Giriş 1 değişmedi
  • Mutlak yolla aynı dosyaya / dizine başvuran göreceli yol

İnce noktalar:

  • İşletim sisteminiz linux ile uyumluysa, giriş olarak almak yerine sistemin geçerli dizinini kullanabilirsiniz
  • Girişlerin yalnızca alfasayısal karakterler (ve yol ayırıcılar) içerdiğini varsayabilirsiniz.
  • Girilen mutlak yolun /sonunda bir yol ayırıcısı olmadığını varsayabilirsiniz.
  • Sen girdi geçerli dizinin yolunu ayırıcı vardır varsayabiliriz /sonunda
  • Mutlak yolun var olan bir dosyaya başvurduğunu veya herhangi bir kısmının erişilebilir bir dizin olduğunu varsayamazsınız; ancak, geçerli dizinin geçerli olduğu varsayılabilir
  • Her iki yolun yakınında herhangi bir sembolik bağ olmadığını varsayabilirsiniz - çünkü sembolik bağlantılarla başa çıkmak için özel bir yol istemiyorum
  • Girişlerden birinin kök dizin olduğu durumu desteklemeye gerek yoktur
  • "Geçerli dizin" çıktısı alınmalıdır .(boş bir dize geçerli değil)

Test senaryoları (giriş1, giriş2, çıkış):

/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
Msgstr "Giriş geçerli dizininin sonunda bir yol ayırıcısı olduğunu varsayabilirsiniz /". Ancak, örneklerinizde durum böyle değildir.
Shaggy

1
Bu şekilde seviyorum, ama bazı insanlar başka bir şekilde
hoşlanıyor


Mutlak ve bağıl yol aynı uzunlukta olursa ne olur?
Dennis

1
Bu bazı kritik test senaryoları eksik: /home/test /home/user/mydir/myfile /home/testve/a/b /a/b/d/e /a/b
Nathan Merrill

Yanıtlar:


7

Julia 0.5 , 32 bayt

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

Bu, geçerli çalışma dizinini temel olarak kullanır ve şu anda TIO'da test edilemez.

Örnek çalışma

Uyarı: Bu, dosya sisteminizi değiştirir.

$ 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")
"."

Alternatif sürüm, 35 bayt (ikili)

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

Bu, temel dizini girdi olarak alır, bu nedenle dosya sistemini değiştirmeden test edilebilir.

Çevrimiçi deneyin!


Base.-Açıkça içe aktarılmadığı sürece hataları yeniden tanımlama , değil mi?
Julian Wolf

0.5'te hata verebilir, ancak yalnızca -yeniden tanımlamadan önce kullanırsanız . 0.4'te, yeniden tanımlamadan önce kullanıp kullanmadığınıza dair bir uyarı yazdırır.
Dennis

9

JavaScript (ES6), 107 106 bayt

Sözdiziminde kesin yolu ave geçerli yolu alır .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||'.'

Test senaryoları


İle çok güzel bir hile [a.length]! Node.js yanıtımı geliştirmek için ödünç alabilir miyim?
zeppelin

@zeppelin Elbette. Göreyim seni!
Arnauld


5

ES6 (Node.js REPL), 56, 54, 46, 45 bayt

  • "." Yerine boş dize kullanın. geçerli dizini (girişte), -1 bayt
  • [f.length]@ Arnauld'un cevabından hüner ödünç alındı , -6 bayt
  • -2 baytlık açık bir dizin parametresi yerine geçerli dizini kullanma
  • Kaldırılan gereksiz parantezler, -2 bayt

golfed

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

Ölçek

> 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 işlevlerine izin vermiyoruz?
Downgoat

@Downgoat Javascript lambdas, bir cevap biçimi olarak yaygın olarak kabul edilmektedir, bu yüzden Node.js'nin neden farklı ele alınması gerektiğini anlamıyorum.
zeppelin

4

Python 2, 135 144 bayt

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)

Çevrimiçi deneyin!

Biraz uzun, ama yerleşik yol fonksiyonları olmadan bir çözüm yapmak istedim.

Düzenleme: Nathan Merrill tarafından sağlanan test davası için hesaba 9 bayt eklendi



2

Python 3-53 bayt

Kullanma os.path:

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

Tam program (61 bayt):

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

Oo, iyi nokta (lar). Python şimdi önde, yay!
matsjoyce

@anatolyg Ha, en az bir test vakasını kaçıracağımı biliyordum ... 😒 Şimdi hepsi düzeltildi.
matsjoyce

1

PHP, 204 Bayt

[,$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:".";

testcases

Expanded

[,$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
    :".";

../../bunun yerine bir Çıktıya of ../..izin verilirse 175 bayta kısaltılabilir

[,$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:".";

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.