В Elisp, как правильно получить строку пути с косой чертой? - PullRequest
10 голосов
/ 14 марта 2012

Я вручную строю строки пути в Elisp, объединяя частичные пути и имена каталогов.К сожалению, иногда пути заканчиваются косой чертой, иногда нет.Поэтому мне нужно вставить косую черту перед конкатенацией имени каталога, когда это необходимо, но не иначе.Какой хороший способ сделать это?

Ответы [ 6 ]

13 голосов
/ 14 марта 2012

(file-name-as-directory dir) вернет путь к каталогу dir с завершающей косой чертой, добавив один, если необходимо, а не иначе.

Если бы у вас была последовательность частичных путей в списке, вы могли бы сделать что-то вроде:

(let ((directory-list '("/foo" "bar/" "p/q/" "x/y"))
      (file-name "some_file.el"))
  (concat
   (mapconcat 'file-name-as-directory directory-list "")
   file-name))

"/foo/bar/p/q/x/y/some_file.el"

или в качестве альтернативы, если вы хотите включить имя файла в список, вы можете использовать directory-file-name, что противоположно file-name-as-directory:

(let ((path-list '("/foo" "bar/" "p/q/" "x/y/some_file.el")))
  (mapconcat 'directory-file-name path-list "/"))

"/foo/bar/p/q/x/y/some_file.el"

(Кто-то, пожалуйста, исправьте меня, если использование directory-file-name на не-директории не является переносимым?)

3 голосов
/ 17 марта 2012

Самый простой способ собрать имена файлов из частей сомнительного контента - это с помощью имени-файла-расширения. Например:

(expand-file-name "foo.txt")

эта общая форма даст вам полное имя файла на основе каталога по умолчанию:

/home/me/foo.txt

но если у вас есть переменная 'dir' с содержимым "/ home / them / subdir" и вы хотите ее использовать, сделайте следующее:

(expand-file-name "foo.txt" dir)

не имеет значения, заканчивается ли каталог dir или нет. Если вы находитесь на какой-то другой платформе и в ней есть другая косая черта, она тоже будет делать то же самое. У вас есть смесь? Просто сложите их:

(expand-file-name "foo.txt" (expand-file-name "somesubdir" dir))
1 голос
/ 18 марта 2012

Если вы действительно не заботитесь о сохранении относительных имен файлов как относительных, всегда лучше избегать concat и использовать expand-file-name вместо.

1 голос
/ 14 марта 2012

Нечто подобное должно работать в качестве отправной точки, хотя вы бы хотели немного прояснить это, чтобы сделать его независимым от платформы и т. Д.

(defun append-path-component (path new-part)
  (if (string-match ".*/$" path)
    (concat path new-part)
    (concat path "/" new-part)))

Как обычно, вероятно, есть кое-что из elisp, которое уже делает это, о чем я просто не знаю.

0 голосов
/ 03 августа 2014

Если вы имеете дело с манипуляциями с файлами, объединением и разделением путей к файлам, проверкой пустых каталогов и т. Д., Я настоятельно рекомендую установить f.el, современную библиотеку для работы с файлами.У вас будет огромный набор функций манипулирования файлами и пути к файлам в одном пространстве имен, и вы никогда не будете заново изобретать колесо.

Вам нужна функция f-join, она объединяет части пути, добавляя косую черту только там, где нужно.

0 голосов
/ 14 марта 2012
(defun* tofilename (directorylist &optional (filename nil))
  "concatenate directory names into a path, with an optional file name as last part"
  (concat
   (mapconcat 'directory-file-name directorylist "/")
   "/"
   filename))


(tofilename '("~/" "Temp/") "temp.txt")
;; => "~/Temp/temp.txt"

(tofilename '("~/" "Temp/"))
;; => "~/Temp/"

(tofilename '("~/" "Temp/" "test"))
;; => "~/Temp/temp/"
...