2011-12-15 10 views
11

Ho un percorso di file costruito in modo dinamico in Haskell che finisce per qualcosa di simile:operazioni di percorso del file oscuro Haskell (semplificare via i punti)

/abc/def/../ghi/./jkl 

e mi piacerebbe per ridurre al più leggibile

/abc/ghi/jkl 

Per la stampa. Esiste una funzione di libreria per fare ciò in haskell? Ho guardato dappertutto e non riesco a trovarne uno. Non è troppo difficile da scrivere, ma è un po 'complicato perché devi "guardare avanti" per ".." s, e preferirei usare una funzione incorporata se possibile.

risposta

15

Attenzione che questa non è semplicemente una questione di elaborazione stringa quando i collegamenti sono coinvolti:

$ mkdir -p foo/bar 
$ ln -s foo/bar baz 
$ echo gotcha! >foo/quux 
$ cat quux 
cat: quux: No such file or directory 
$ cat baz/../quux 
gotcha! 

Quindi è necessario fare IO.

Il più vicino possibile trovare quello che vuoi è canonicalizePath da System.Directory. Restituisce un percorso a partire dalla directory root, quindi potresti volerlo usare in congiunzione con makeRelative, anche da System.Directory. Ma funziona in IO.

2

Dai uno sguardo allo System.FilePath.Posix. La funzione normalise fa quasi ciò che si vuole:

> normalise "/abc/def/../ghi/./jkl" 
"/abc/def/../ghi/jkl" 

si potrebbe usare splitDirectories per dividere il nome del file e semplificare l'elaborazione.

Beware of casi limite quali:

/../foo  -- Equal to /foo, at least on my system 
../parent/foo -- Requires a system call to eliminate the possibly-redundant .. 
Problemi correlati