Как получить базовое имя в ruby ​​из заданного пути к файлу в формате unix или windows?

Мне нужно разобрать базовое имя в ruby ​​из пути к файлу, который я получаю в качестве входных данных. Формат Unix отлично работает в Linux.

File.basename("/tmp/text.txt")

вернуть "text.txt".
Однако, когда я получаю ввод в формате Windows:

File.basename("C:\Users\john\note.txt")

или

File.basename("C:\\Users\\john\\note.txt")

«C:Usersjohn\note.txt» — это вывод (обратите внимание, что \n — это новая строка), но я не получил «note.txt».

Есть ли хорошее решение в ruby/rails?

Решение:

"C:\\test\\note.txt".split(/\\|//).last
=> "note.txt"
"/tmp/test/note.txt".split(/\\|//).last
=> "note.txt"

Если имя файла Linux не содержит \, оно будет работать.

Примечание: "C:\U".chars #=> ["C", ":", "U"].

Cary Swoveland 08.03.2019 21:54

@CarySwoveland Дополнительное примечание «\ note» рассматривается как символ новой строки (\n) ote.txt.

engineersmnky 08.03.2019 22:19
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
2
572
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Попробуйте pathname:

require 'pathname'

Pathname.new('C:\Users\john\note.txt').basename
# => #<Pathname:note.txt>

Документы пути

Ссылка Как получить имя файла без расширения из пути к файлу в Ruby

@CarySwoveland, что ты имеешь в виду?

Martin Zinovsky 08.03.2019 21:58

В OP использовались двойные кавычки без обратной косой черты.

Cary Swoveland 08.03.2019 21:59

Кажется, это не работает в Linux с использованием 2.6.1 Pathname.new('C:\Users\john\note.txt').basename #=> #<Pathname:C:\Users\john\note.txt>

engineersmnky 08.03.2019 22:05

@engineersmnky Это не будет работать в Linux, потому что Linux не обрабатывает обратную косую черту так же, как Windows.

tadman 08.03.2019 23:28

@tadman моя точка зрения заключалась в том, что маловероятно, что сервер rails работает через IIS, поэтому это может быть нежизнеспособным вариантом.

engineersmnky 08.03.2019 23:37

Спасибо, но это не работает так, как File.basename в Linux ruby.

malmed 11.03.2019 11:51
Ответ принят как подходящий

Обратная косая черта, в то время как Windows выражает вещи, просто гигантская неприятность. В строке с двойными кавычками они имеют особое значение, поэтому вам нужно сделать следующее:

File.basename("C:\\Users\\john\\note.txt")

Или используйте одинарные кавычки, чтобы избежать проблемы:

File.basename('C:\Users\john\note.txt')

Или используйте обычные косые черты, которые не затронуты:

File.basename("C:/Users/john/note.txt")

Где Ruby выполняет сопоставление для вас с разделителем пути для конкретной платформы.

Первые два у меня не работали на macos. Полагаю, из-за File::SEPARATOR. Итак, если не считать запуска этого кода в Windows. вызывающая сторона должна преобразовать косые черты в качестве шага предварительной обработки. :пожимаю плечами:

Sergio Tulentsev 11.03.2019 11:38

Кажется, что единственный способ - заменить `и` на /, а затем проанализировать его как путь к файлу Unix. Или испортите File::ALT_SEPARATOR. В любом случае, это изменит имена файлов Unix, такие как /tmp/test\file.txt :(

malmed 11.03.2019 12:07

Я не уверен, что у вас проблемы с кодом. Я думаю, у вас проблемы с тестом.

Ruby также использует символ обратной косой черты для escape-последовательности в строках, поэтому, когда вы вводите строковый литерал "C:\Users\john\note.txt", Ruby рассматривает первые два символа обратной косой черты как недопустимые escape-последовательности и поэтому игнорирует escape-символ. \n относится к новой строке. Итак, для Ruby этот литерал такой же, как "C:Usersjohn\note.txt". В этой последовательности нет разделителей файлов, поскольку \n — это новая строка, а не обратная косая черта, за которой следует буква н, поэтому File.basename просто возвращает ее по мере ее получения.

Если вы запрашиваете пользовательский ввод либо в графическом пользовательском интерфейсе (GUI), либо в интерфейсе командной строки (CLI), пользователю, вводящему ввод, не нужно беспокоиться об управляющих последовательностях Ruby String; они имеют значение только для строковых литералов непосредственно в коде. Попытайся! Введите gets в IRB или Прай, введите или скопируйте путь к файлу, нажмите Enter и посмотрите, как Ruby отображает его как строковый литерал.

В Windows Ruby принимает пути, указанные с использованием как «/» (File::SEPARATOR), так и «\\» (Файл::ALT_SEPARATOR), поэтому вам не нужно беспокоиться о преобразовании, если вы не показываете его пользователю.

Вы правы с gets -> "C:\\Users\\john\\note.txt\n". Однако в Linux Ruby/Rails ни File, ни Pathname не могут его разобрать.

malmed 11.03.2019 11:46

@malmed: я сейчас не в Windows, поэтому не могу проверить, но я уверен, что и файл, и путь должны нормально обрабатывать «C:\\Users\\john\\note.txt». Я подозреваю, что проблема заключается в конце новой строки (\n). Используйте String#chop.

sondra.kinsey 13.03.2019 19:05

Я тоже не на винде (но оба формата пути получаю). Я не сомневаюсь, что "C:\\Users\\john\\note.txt" нормально разбирается в Windows.

malmed 14.03.2019 20:55

@malmed Вы хотите, чтобы пользователь ввел путь к файлу в веб-приложение, а затем ваше приложение манипулировало этим путем? Мне трудно представить себе вариант использования для этого. Очевидно, вы можете просто использовать String#split.

sondra.kinsey 14.03.2019 21:04

Другие вопросы по теме