команда bash/fish для печати абсолютного пути к файлу
вопрос: есть ли простой 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)
17 ответов
$ readlink -m FILE
/path/to/FILE
Это лучше, чем readlink -e FILE
или realpath
, потому что он работает, даже если файл не существует.
забудь о readlink
и realpath
который может быть установлен или не установлен в вашей системе.
расширения dogbane это выше здесь это выражается как функция:
#!/bin/bash
get_abs_filename() {
# : relative filename
echo "$(cd "$(dirname "")" && pwd)/$(basename "")"
}
вы можете использовать его следующим образом:
myabsfile=$(get_abs_filename "../../foo/bar/file.txt")
как и почему это работает?
решение использует тот факт, что встроенный Bash pwd
команда напечатает абсолютный путь текущего каталога при вызове без аргументы.
почему мне нравится это решение ?
это портативный и не требует ни readlink
или realpath
который часто не существует при установке по умолчанию данного дистрибутива Linux/Unix.
что, если dir не существует?
как указано выше, функция завершится ошибкой и напечатает на stderr, если указанный путь к каталогу не существует. Это может быть не то, чего ты хочешь. Вы можете развернуть функцию, чтобы обработать это ситуация:
#!/bin/bash
get_abs_filename() {
# : relative filename
if [ -d "$(dirname "")" ]; then
echo "$(cd "$(dirname "")" && pwd)/$(basename "")"
fi
}
теперь он вернет пустую строку, если один родительский dirs не существует.
как вы обрабатываете трейлинг '..' или.' - во вводе ?
Ну, в этом случае он дает абсолютный путь, но не минимальный. Это будет выглядеть так:
/Users/bob/Documents/..
если вы хотите решить '.. вам нужно будет сделать скрипт типа:
get_abs_filename() {
# : relative filename
filename=
parentdir=$(dirname "${filename}")
if [ -d "${filename}" ]; then
echo "$(cd "${filename}" && pwd)"
elif [ -d "${parentdir}" ]; then
echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
fi
}
этот относительный путь к абсолютному пути конвертер функция Shell
- не требует никаких утилит (просто
cd
иpwd
) - работает для каталогов и файлов
- ручки
..
и.
- обрабатывает пробелы в dir или имена
- требует, чтобы файл или каталог существовал
- возвращает nothing, если ничего не существует в данном пути
- ручки абсолютные пути в качестве входных данных (пропускает их через себя)
код:
function abspath() {
# generate absolute path from relative path
# : relative filename
# return : absolute path
if [ -d "" ]; then
# dir
(cd ""; pwd)
elif [ -f "" ]; then
# file
if [[ = /* ]]; then
echo ""
elif [[ == */* ]]; then
echo "$(cd "${1%/*}"; pwd)/${1##*/}"
else
echo "$(pwd)/"
fi
fi
}
пример:
# assume inside /parent/cur
abspath file.txt => /parent/cur/file.txt
abspath . => /parent/cur
abspath .. => /parent
abspath ../dir/file.txt => /parent/dir/file.txt
abspath ../dir/../dir => /parent/dir # anything cd can handle
abspath doesnotexist => # empty result if file/dir does not exist
abspath /file.txt => /file.txt # handle absolute path input
Примечание: это основано на ответы от nolan6000 и bsingh, но исправляет дело.
я также понимаю, что первоначальный вопрос касался существующей утилиты командной строки. Но поскольку это, похоже, вопрос о stackoverflow для этого, включая сценарии оболочки, которые хотят иметь минимальные зависимости, я помещаю это решение скрипта здесь, поэтому я могу найти его позже:)
на может поможет
find $PWD -name ex*
find $PWD -name example.log
перечисляет все файлы в или ниже текущего каталога с именами, соответствующими шаблону. Вы можете упростить его, если получите только несколько результатов (например, каталог в нижней части дерева, содержащий несколько файлов), просто
find $PWD
Я использую это на Solaris 10, в котором нет других упомянутых утилит.
Если у вас нет утилит readlink или realpath, вы можете использовать следующую функцию, которая работает в bash и zsh (не уверен в остальном).
abspath () { case "" in /*)printf "%s\n" "";; *)printf "%s\n" "$PWD/";; esac; }
Это также работает для несуществующих файлов (как и функция python os.path.abspath
).
к сожалению abspath ./../somefile
не избавляется от точек.
вот функция zsh-only, которая мне нравится за ее компактность. Он использует модификатор расширения " A " - см. zshexpn(1).
realpath() { for f in "$@"; do echo ${f}(:A); done }
обычно нет такой вещи, как the absolute path
в файл (это утверждение означает, что может быть более одного в целом, следовательно, использование определенной статьи the не подходит). Ан absolute path
- Это любой путь, который начинается с корня " / " и обозначает файл без двусмысленности независимо от рабочего каталога.(см., например,Википедия).
A relative path
- это путь, который интерпретируется, начиная с другой каталог. Это может быть рабочий каталог, если это relative path
манипулирование приложением
(хотя и не обязательно). Когда он находится в символической ссылке в каталоге, он обычно предназначен для относительного этого каталога (хотя пользователь может иметь в виду другое использование).
следовательно, абсолютный путь-это просто путь относительно корневого каталога.
путь (абсолютный или относительный) может содержать или не содержать символические ссылки. Если это не так, это также несколько невосприимчивы к изменениям в структуре связей, но это не обязательно требуется или даже желательно. Некоторые люди называют canonical path
( или canonical file name
или resolved path
) an absolute path
в котором все символические ссылки были разрешены, т. е. были заменены путем к тому, на что они ссылаются. Команды realpath
и readlink
оба ищут канонический путь, но только realpath
имеет возможность получить абсолютный путь, не беспокоясь о разрешении символических ссылок (наряду с несколькими другими вариантами, чтобы получить различные вид путей, абсолютный или относительный к некоторому каталогу).
это требует нескольких замечаний:
- символические ссылки могут быть разрешены только в том случае, если они должны
ссылка на уже создана, что, очевидно, не всегда так. Команды
realpath
иreadlink
есть варианты для учета этого. - каталог на пути может позже стать символической ссылкой, Что означает, что путь больше не
canonical
. Следовательно, понятие-это время (или среды) зависит. - даже в идеальном случае, когда все символические ссылки могут быть решены,
может быть, их еще несколько!--4--> в файл, для двух
причины:
- раздел, содержащий файл, возможно, был смонтирован одновременно (
ro
) на нескольких точках крепления. - могут быть жесткие ссылки на файл, что означает, что файл существует в нескольких разных каталогах.
- раздел, содержащий файл, возможно, был смонтирован одновременно (
следовательно, даже с гораздо более ограничительное определение canonical path
, там может быть несколько канонических путей к файлу. Это также означает, что квалификатор canonical
несколько неадекватен, поскольку обычно подразумевает понятие уникальности.
это расширяет краткое обсуждение темы в ответе на другой аналогичный вопрос в Bash: получить абсолютный путь, заданный относительным
мой вывод таков realpath
лучше разработан и гораздо более гибкий, чем readlink
.
Этот только использование readlink
это не покрывается realpath
- это вызов без опции, возвращающей значение символической ссылки.
для каталогов dirname
попадется на ../
и возвращает ./
.
nolan6000 это можно изменить, чтобы исправить это:
get_abs_filename() {
# : relative filename
if [ -d "${1%/*}" ]; then
echo "$(cd ${1%/*}; pwd)/${1##*/}"
fi
}
Я разместил следующий скрипт в своей системе , и я называю его псевдонимом bash, когда я хочу быстро захватить полный путь к файлу в текущем каталоге:
#!/bin/bash
/usr/bin/find "$PWD" -maxdepth 1 -mindepth 1 -name ""
Я не уверен, почему, но в OS X при вызове скриптом "$PWD " расширяется до абсолютного пути. Когда команда find вызывается в командной строке, это не так. Но он делает то, что я хочу... наслаждаться.
The dogbane
ответ С описанием того, что происходит:
#! /bin/sh
echo "$(cd "$(dirname "")"; pwd)/$(basename "")"
объяснение:
- этот скрипт получает относительный путь в качестве аргумента
""
- тогда мы получим dirname часть этого пути (вы можете передать либо dir, либо файл в этот скрипт):
dirname ""
- затем мы
cd "$(dirname "")
в этот относительный dir и получить абсолютный путь для него, запустивpwd
shell command - после этого мы добавить имени абсолютный путь:
$(basename "")
- в качестве заключительного шага мы
echo
это
#! /bin/bash
file="$@"
realpath "$file" 2>/dev/null || eval realpath $(echo $file | sed 's/ /\ /g')
это компенсирует недостатки realpath
, хранить его в shell-скрипт fullpath
. Теперь вы можете позвонить:
$ cd && touch a\ a && rm A 2>/dev/null
$ fullpath "a a"
/home/user/a a
$ fullpath ~/a\ a
/home/user/a a
$ fullpath A
A: No such file or directory.
Это не ответ на вопрос, но для тех, кто делает скрипты:
echo `cd "" 2>/dev/null&&pwd||(cd "$(dirname "")";pwd|sed "s|/*$|/${1##*/}|")`
он обрабатывает / .. ./ и т. д. Правильно. Я также, кажется, работаю над OSX
Альтернатива для получения абсолютного пути в Рубин:
realpath() {ruby -e "require 'Pathname'; puts Pathname.new('').realpath.to_s";}
работает без аргументов (текущая папка) и относительного и абсолютного пути к файлу или папке как agument.
Эй, ребята, я знаю, что это старая нить, но я просто публикую это для ссылки на кого-либо еще, кто посетил это, как я. Если я правильно понял вопрос, я думаю . Он отображает абсолютный путь к файлу, но только если он существует.