Вопрос: существует ли простая команда sh / bash / zsh / fish / ... для печати абсолютного пути к файлу, который я передаю?
Случай использования: Я нахожусь в директории , /a/b
и я хотел бы, чтобы напечатать полный путь к файлу c
в командной строке , так что я могу легко вставить его в другую программу: /a/b/c
. Простая, но небольшая программа для этого, вероятно, может сэкономить мне около 5 секунд, когда дело доходит до обработки длинных путей, что в итоге складывается. Поэтому меня удивляет, что я не могу найти стандартную утилиту для этого - неужели ее нет?
Вот пример реализации, abspath.py:
#!/usr/bin/python
# Author: Diggory Hardy <diggory.hardy@gmail.com>
# Licence: public domain
# Purpose: print the absolute path of all input paths
import sys
import os.path
if len(sys.argv)>1:
for i in range(1,len(sys.argv)):
print os.path.abspath( sys.argv[i] )
sys.exit(0)
else:
print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
sys.exit(1)
Ответы:
Попробуй
realpath
.источник
realpath
: github.com/westonruter/misc-cli-tools/blob/master/realpathПопробуйте
readlink
разрешить символические ссылки:источник
-m
это лучший вариант для использования./usr/bin/readlink
на Маверикс. Или вы имели в виду, что эти опции не найдены в OS X? Кажется, что это чахлая версия BSD ...: preadlink
страница руководства:only the target of the symbolic link is printed. If the given argument is not a symbolic link, readlink will print nothing and exit with an error
так readlink не будет работать для этой цели на OSXисточник
a b
(два пробела между a и b, SO ест один из них).function realpath { echo $(cd $(dirname $1); pwd)/$(basename $1); }
чтобы сделать себеrealpath
команду (в настоящее время принятый ответ) на OS X. Спасибо!LOG=$(echo $(cd $(dirname $0); pwd)/$(basename $0 .sh).log)
Забудьте о
readlink
иrealpath
которые могут или не могут быть установлены на вашей системе.Развивая ответ кендырь в выше здесь выражается в виде функции:
затем вы можете использовать его так:
Как и почему это работает?
Решение использует тот факт, что встроенная
pwd
команда Bash будет печатать абсолютный путь к текущему каталогу при вызове без аргументов.Почему мне нравится это решение?
Это портативное и не требует ни
readlink
илиrealpath
что часто не существует по дефолту не установить данный Linux / Unix дистрибутив.Что если dir не существует?
Как указано выше, функция потерпит неудачу и напечатает на stderr, если указанный путь к каталогу не существует. Это может быть не то, что вы хотите. Вы можете расширить функцию для обработки этой ситуации:
Теперь он вернет пустую строку, если один из родительских каталогов не существует.
Как вы справляетесь с ".." или "." на входе?
Ну, это дает абсолютный путь в этом случае, но не минимальный. Это будет выглядеть так:
Если вы хотите разрешить «..», вам нужно сделать скрипт следующим образом:
источник
realpath
поставляется из пакета coreutils, который также содержит такие инструменты, какwho
,touch
илиcat
. Это довольно стандартный набор инструментов GNU, так что вы можете быть уверены, что он установлен практически на любой машине под управлением Linux. Тем не менее, вы правы: с ним есть 2 проблемы: i) вы, скорее всего, пропустите его при установке по умолчанию на не GNU unix системы (такие как OpenBSD) ii) этот инструмент был представлен в версии 8.15 (так что он довольно новый, начиная с 2012 года), так что вы пропустите его в долгосрочных стабильных системах (например, RHEL 6).Это лучше чем
readlink -e FILE
илиrealpath
, потому что это работает, даже если файл не существует.источник
-m
опция не доступна на Маверикс.Этот относительный путь к функции оболочки конвертера абсолютного пути
cd
иpwd
)..
и.
Код:
Образец:
Примечание: это основано на ответах от nolan6000 и bsingh , но исправляет регистр файлов.
Я также понимаю, что первоначальный вопрос был о существующей утилите командной строки. Но так как это, кажется, вопрос о стеке потока для этого, включая сценарии оболочки, которые хотят иметь минимальные зависимости, я поместил это решение сценария здесь, чтобы найти его позже :)
источник
$ abspath 'a b c/file.txt'
это потому, что аргумент tocd
не заключен в кавычки. Чтобы преодолеть это, вместо цитирования всего аргументаecho
(есть ли причина для этих кавычек?) Указывайте только аргументы пути. Т.е. заменитьecho "$(cd ${1%/*}; pwd)/${1##*/}"
наecho $(cd "${1%/*}"; pwd)/${1##*/}
.echo "$(cd "$1"; pwd)"
на(cd "$1"; pwd)
. Здесь нет необходимости для эха.( ... )
по-прежнему необходимы, поэтому этоcd
происходит в подоболочке, так как мы не хотим менять рабочий каталог для любых вызывающихabspath
.Команда
find
может помочьПеречисляет все файлы в или ниже текущего каталога с именами, соответствующими шаблону. Вы можете упростить его, если получите только несколько результатов (например, каталог в нижней части дерева, содержащий несколько файлов), просто
Я использую это в Solaris 10, в котором нет других упомянутых утилит.
источник
PWD
, вы можете просто использовать$PWD/$filename
.Если у вас нет утилит readlink или realpath, вы можете использовать следующую функцию, которая работает в bash и zsh (не уверен насчет остальных).
Это также работает для несуществующих файлов (как и функция python
os.path.abspath
).К сожалению
abspath ./../somefile
, не избавляется от точек.источник
echo "$1"
наprintf "%s\n" "$1"
(то же самое со вторым эхом).echo
может интерпретировать обратную косую черту внутри своих аргументов.Вот функция zsh-only, которая мне нравится за ее компактность. Он использует модификатор расширения 'A' - см. Zshexpn (1).
источник
Существует правило , нет такого понятия , как в файл (это утверждение означает , что там может быть больше , чем один в целом, поэтому использование определенного артикля не подходит). An - это любой путь, начинающийся с корня "/" и обозначающий файл без неоднозначности независимо от рабочего каталога (см., Например, википедию ).
absolute path
absolute path
A
relative path
- это путь, который должен интерпретироваться, начиная с другого каталога. Это может быть рабочий каталог, если имrelative path
манипулирует приложение (хотя и не обязательно). Когда он находится в символической ссылке в каталоге, он, как правило, предназначен для связи с этим каталогом (хотя пользователь может иметь в виду и другое использование).Следовательно, абсолютный путь - это просто путь относительно корневого каталога.
Путь (абсолютный или относительный) может содержать или не содержать символические ссылки. Если это не так, это также несколько непроницаемо для изменений в структуре связи, но это не обязательно требуется или даже желательно. Некоторые люди называют
canonical path
(илиcanonical file name
илиresolved path
) a,absolute path
в котором все символические ссылки были разрешены, т.е. были заменены путем к тому, на что они ссылаются. Командыrealpath
иreadlink
обе ищут канонический путь, но толькоrealpath
имеют возможность получить абсолютный путь, не удосуживаясь разрешить символические ссылки (наряду с несколькими другими опциями, чтобы получить различные типы путей, абсолютные или относительные к некоторому каталогу).Это требует нескольких замечаний:
realpath
иreadlink
опции для учета этого.canonical
. Следовательно, концепция зависит от времени (или окружающей среды).canonical path
в файле может быть больше одной ссылки по двум причинам:ro
) в нескольких точках монтирования.Следовательно, даже с гораздо более ограничительным определением
canonical path
, может быть несколько канонических путей к файлу. Это также означает, что классификаторcanonical
несколько неадекватен, поскольку обычно подразумевает понятие уникальности.Это расширяет краткое обсуждение темы в ответе на другой похожий вопрос в Bash: получить абсолютный путь относительно
Мой вывод заключается в том, что
realpath
лучше разработан и гораздо более гибким, чемreadlink
. Единственное использованиеreadlink
этого не распространяетсяrealpath
на вызов без опции, возвращающей значение символической ссылки.источник
realpath
противreadlink
или даже о символических ссылках излишни к тому, что я спросил.canonical
относится именно к этой уникальности относительно набора преобразований. Но, например, / dev / cdrom - это абсолютно хороший абсолютный путь, хотя на самом деле это ссылка на / dev / sr0. Оба указывают на одно и то же устройство. Мой оригинальный ответ указывал на соответствующую веб-статью.dogbane
Ответ с описанием того, что грядет на:Объяснение:
"$1"
dirname "$1"
cd "$(dirname "$1")
в этот относительный каталог и получаем абсолютный путь для него, выполняяpwd
команду оболочки$(basename "$1")
echo
этоисточник
Для каталогов
dirname
срабатывает../
и возвращается./
.Функцию nolan6000 можно изменить, чтобы исправить это:
источник
.profile
и, следовательно, доступна для интерактивного использования.$1
указано простое имя файла:get_abs_filename foo
-> none (или<current_dir>/foo/foo
iffoo
является каталогом).Это не ответ на вопрос, а для тех, кто занимается сценариями:
он обрабатывает / .. ./ и т. д. правильно. У меня тоже вроде работает на OSX
источник
Я поместил следующий скрипт в мою систему, и я называю его псевдонимом bash, когда я хочу быстро получить полный путь к файлу в текущем каталоге:
Я не уверен, почему, но в OS X при вызове сценария «$ PWD» расширяется до абсолютного пути. Когда команда find вызывается из командной строки, это не так. Но он делает то, что я хочу ... наслаждайся.
источник
$PWD
всегда имеет абсолютный путь рабочего каталога. Кроме того,find
не будет терпеть косые черты, поэтому вы не отвечаете на вопрос, который задали. Более быстрый способ сделать то , что вы хотите сделать , было бы простоecho "$PWD/$1"
Самое простое, если вы хотите использовать только встроенные функции:
Только два лишних слова для ввода, и это будет работать на всех системах Unix, а также OSX.
источник
-maxdepth 1
раньше-name
(предположим, что файл находится в текущем каталоге). Без этого он будет работать с файлами в любом подкаталоге pwd, но не с другими.find
не найти файл за пределами дерева каталогов внизуpwd
. Например, если вы попытаетесьfind . -name ../existingFile
, это не удастся.Это восполняет недостатки
realpath
, храните его в сценарии оболочкиfullpath
. Теперь вы можете позвонить:источник
realpath "foo bar"
->/home/myname/foo bar
. Если вы не можете взять в кавычки аргументы командной строки, это неrealpath
вина.Альтернатива для получения абсолютного пути в Ruby :
realpath() {ruby -e "require 'Pathname'; puts Pathname.new('$1').realpath.to_s";}
Работает без аргументов (текущая папка) и относительного и абсолютного пути к файлу или папке в качестве аргумента.
источник
Ответить с Homebrew
realpath
лучший ответ, но если он не установлен, сначала нужно запуститьbrew install coreutils
чтобы установить coreutils с множеством потрясающих функций. Написание пользовательской функции и ее экспорт - это слишком много работы и риск ошибки для чего-то подобного, вот две строки:источник
Привет, ребята, я знаю, что это старая ветка, но я просто отправляю это для ссылки любому, кто посетил это, как я. Если я правильно понял вопрос, думаю,
locate $filename
команда. Он отображает абсолютный путь к предоставленному файлу, но только если он существует.источник
locate
утилита для поиска файлов / путей по имени Он может выполнять эту работу, но также может находить другие совпадения и может не найти существующий файл, не вызвавupdatedb
сначала root.