Как получить полный путь к файлу?


719

Есть ли простой способ напечатать полный путь file.txt?

file.txt = /nfs/an/disks/jj/home/dir/file.txt

<command>

dir> <command> file.txt  

должен напечатать

/nfs/an/disks/jj/home/dir/file.txt

Ответы:


1189

Используйте readlink :

readlink -f file.txt

32
Вот для чего -f.
фильм


5
Только что протестировал на 10.9.2, отлично работает. который читает ссылку / usr / local / opt / coreutils / libexec / gnubin / readlink readlink
версия

10
@ J0hnG4lt: это потому, что вы установили coreutils с помощью homebrew и изменили путь PATH, чтобы он указывал на нефиксированные двоичные файлы. Установка coreutils, оставление PATH в покое и использование «greadlink» также будет работать.
Тим Смит

35
на MAC: установить доморощенного затем brew install coreutilsзатемgreadlink -f file.txt
к Кра

217

Я полагаю, вы используете Linux.

Я нашел утилиту под названием realpathcoreutils 8.15.

realpath file.txt
/data/ail_data/transformed_binaries/coreutils/test_folder_realpath/file.txt

Согласно комментариям @ styrofoam-fly и @ arch-standton, realpathодин не проверяет существование файла, для решения этой проблемы добавьте eаргумент:realpath -e file


Работает с Cygwin (с Mintty 2.7.9)
Scrambo

1
realpathбыло совершено репо coreutils в конце 2011 года, выпуск 8.15 был сделан в январе 2012 года, я ответил на вопрос (с readlinkпредложением) в марте 2011 года :)
filmor

2
realpath не проверяет существование файла, он просто разрешает пути. Запрос полного пути к несуществующему файлу должен привести к ошибке.
пенополистирол, перелет

4
@styrofoamfly realpath -eпечатает ошибку, если аргумент не существует.
Arch Stanton

77

Следующее обычно делает трюк:

 echo $(cd $(dirname "$1") && pwd -P)/$(basename "$1")

Привет. Я нашел этот ответ лучше всего на мое требование. Можете ли вы объяснить, как я могу использовать локальную переменную вместо параметра командной строки (то есть $ 1)
deeJ

1
LOCAL_VARIABLE="filename.txt" && echo $(cd $(dirname "$LOCAL_VARIABLE") && pwd -P)/$(basename "$LOCAL_VARIABLE")
stiemannkj1

7
@SopalajodeArrierez Поскольку readlinkне работает, если файл является символической ссылкой, он покажет вам цель символической ссылки вместо самой символической ссылки.
qwertzguy

1
Мне это нравится, потому что readlinkвозвращает меня к родительскому каталогу, из которого генерируется символическая ссылка, но это игнорирует его.
Сухи

set .. && echo $(cd $(dirname "$1") && pwd -P)/$(basename "$1") ### Вывод: / home / ravi / ..
Том Хейл

35

Я знаю, что есть более простой способ, но, черт возьми, если я смогу это найти ...

jcomeau@intrepid:~$ python -c 'import os; print(os.path.abspath("cat.wav"))'
/home/jcomeau/cat.wav

jcomeau@intrepid:~$ ls $PWD/cat.wav
/home/jcomeau/cat.wav

26
find $PWD -type f | grep "filename"

или

find $PWD -type f -name "*filename*"

1
Для меня на Mac это сработало - вместо $ pwd -find `pwd` -type file -name \*.dmp
mrwaim

14

Если вы находитесь в том же каталоге, что и файл:

ls "`pwd`/file.txt"

Замените file.txtна целевое имя файла.


9
Вы также можете сделатьecho $(pwd)/file.txt
Алекс

12

В Windows:

  • Удерживая Shiftи щелкая правой кнопкой мыши файл в проводнике Windows, вы получаете опцию под названием Copy as Path. Это скопирует полный путь к файлу в буфер обмена.

В Linux:

  • Вы можете использовать команду, realpath yourfileчтобы получить полный путь к файлу, как предложено другими.

4

Я знаю, что это старый вопрос сейчас, но просто добавить к информации здесь:

Команду Linux whichможно использовать для поиска пути к файлу команды, т.е.

$ which ls
/bin/ls

Есть несколько предостережений к этому; пожалуйста, смотрите https://www.cyberciti.biz/faq/how-do-i-find-the-path-to-a-command-file/ .


5
Этот ответ слишком конкретен, OP не о поиске команд.
AL

4

Работает на Mac, Linux, * nix:

Это даст вам CSV всех файлов в текущем каталоге:

ls | xargs -I {} echo "$(pwd -P)/{}" | xargs | sed 's/ /","/g'

Вывод этого может быть легко скопирован в список Python или любую аналогичную структуру данных.


печатает текущий путь pwd
Sand1512

Да, разделенные запятыми полные пути для всех файлов в pwd, для файла просто введите ls 'filename' вместо просто 'ls'.
Бхаргав Шринивасан

3

Вы можете использовать скрипт fpn (полное имя пути) :

% pwd
/Users/adamatan/bins/scripts/fpn

% ls
LICENSE   README.md fpn.py

% fpn *
/Users/adamatan/bins/scripts/fpn/LICENSE
/Users/adamatan/bins/scripts/fpn/README.md
/Users/adamatan/bins/scripts/fpn/fpn.py

fpnэто не стандартный пакет Linux, но это бесплатный и открытый проект github, и вы можете настроить его за минуту .


1
Как правило, pwdсамо по себе должно нормально работать в Linux и большинстве других Unix-подобных ОС.
Каролус

3

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

abspath() { old=`pwd`;new=$(dirname "$1");if [ "$new" != "." ]; then cd $new; fi;file=`pwd`/$(basename "$1");cd $old;echo $file; }

Применение:

$ abspath file.txt
/I/am/in/present/dir/file.txt

Использование с относительным путем:

$ abspath ../../some/dir/some-file.txt
/I/am/in/some/dir/some-file.txt

С пробелами в имени файла:

$ abspath "../../some/dir/another file.txt"
/I/am/in/some/dir/another file.txt

2

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

set script_dir = `pwd`/`dirname $0`

$0 хранит точную строку, как скрипт был выполнен.

Для , например , если сценарий был запущен как это: $> ../../test/test.csh, $script_dirбудет содержать/home/abc/sandbox/v1/../../test


за это проголосовали, так как это самый простой и актуальный вариант. Однако, если вы напечатаете, у ./test.cshвас будет путь, заканчивающийся на/test/.
vinyll

2

Для Mac OS X я заменил утилиты, поставляемые с операционной системой, и заменил их более новой версией coreutils. Это позволяет вам получать доступ к таким инструментам, как readlink -f(для абсолютного пути к файлам) и realpath(абсолютному пути к каталогам) на вашем Mac.

Версия Homebrew добавляет «G» (для инструментов GNU) перед именем команды - так что эквиваленты становятся greadlink -f FILEи grealpath DIRECTORY.

Инструкции по установке coreutils / GNU Tools на Mac OS X через Homebrew можно найти в этой статье StackExchange .

NB: readlink -fи realpathкоманды должны работать из коробки для пользователей , не Mac Unix.


2
brew install coreutils
Кра

2
echo $(cd $(dirname "$1") && pwd -P)/$(basename "$1")

Это объяснение того , что происходит на @ ZeRemz в ответ :

  1. Этот скрипт получает относительный путь в качестве аргумента "$1"
  2. Затем мы получаем часть dirname этого пути (вы можете передать dir или file в этот скрипт):dirname "$1"
  3. Тогда мы cd "$(dirname "$1")в этот относительный реж
  4. && pwd -Pи получить абсолютный путь для этого. -Pопция позволит избежать всех символических ссылок
  5. После этого мы добавляем basename к абсолютному пути:$(basename "$1")
  6. В качестве последнего шага мы echoэто

1

Это хорошо сработало для меня. Он не зависит от файловой системы (pro / con в зависимости от необходимости), поэтому он будет быстрым; и он должен быть переносимым для большинства * NIX. Предполагается, что переданная строка действительно относится к PWD, а не к какому-либо другому каталогу.

function abspath () {
   echo $1 | awk '\
      # Root parent directory refs to the PWD for replacement below
      /^\.\.\// { sub("^", "./") } \
      # Replace the symbolic PWD refs with the absolute PWD \
      /^\.\//   { sub("^\.", ENVIRON["PWD"])} \
      # Print absolute paths \
      /^\//   {print} \'
}

1

Это наивно, но я должен был сделать это, чтобы быть POSIX-совместимым. Требуется разрешение для CD в каталог файла.

#!/bin/sh
if [ ${#} = 0 ]; then
  echo "Error: 0 args. need 1" >&2
  exit 1
fi


if [ -d ${1} ]; then


  # Directory


  base=$( cd ${1}; echo ${PWD##*/} )
  dir=$( cd ${1}; echo ${PWD%${base}} )

  if [ ${dir} = / ]; then
    parentPath=${dir}
  else
    parentPath=${dir%/}
  fi

  if [ -z ${base} ] || [ -z ${parentPath} ]; then
    if [ -n ${1} ]; then
      fullPath=$( cd ${1}; echo ${PWD} )
    else
      echo "Error: unsupported scenario 1" >&2
      exit 1
    fi
  fi

elif [ ${1%/*} = ${1} ]; then

  if [ -f ./${1} ]; then


    # File in current directory

    base=$( echo ${1##*/} )
    parentPath=$( echo ${PWD} )

  else
    echo "Error: unsupported scenario 2" >&2
    exit 1
  fi
elif [ -f ${1} ] && [ -d ${1%/*} ]; then


  # File in directory

  base=$( echo ${1##*/} )
  parentPath=$( cd ${1%/*}; echo ${PWD} )

else
  echo "Error: not file or directory" >&2
  exit 1
fi

if [ ${parentPath} = / ]; then
  fullPath=${fullPath:-${parentPath}${base}}
fi

fullPath=${fullPath:-${parentPath}/${base}}

if [ ! -e ${fullPath} ]; then
  echo "Error: does not exist" >&2
  exit 1
fi

echo ${fullPath}

0

Как правило:

find `pwd` | grep <filename>

В качестве альтернативы, только для текущей папки:

find `pwd` -maxdepth 1 | grep <filename>

хм, почему ненавижу?
Sjas

0

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

dirname `readlink -e relative/path/to/file`

Который будет возвращать полный путь fileот корневого пути и далее. Это можно использовать в скрипте, чтобы скрипт знал, по какому пути он работает, что полезно в клоне репозитория, который может находиться в любом месте на машине.

basePath=`dirname \`readlink -e $0\``

Затем я могу использовать ${basePath}переменную в моих сценариях для прямой ссылки на другие сценарии.

Надеюсь это поможет,

Дейв


0

Вы можете сохранить это в своей shell.rcили просто положить в консоль

function absolute_path { echo "$PWD/$1"; }
alias ap="absolute_path"

пример:

ap somefile.txt

будет выводить

/home/user/somefile.txt

3
Но потом ap ../foobar.txtдаст /home/user/../foobar.txt, что не совсем то, что вы хотите.
Bdesham

2
И ap /tmp/foobar.txtдаст /home/user//tmp/foobar.txt, что не так.
Дэвид Дан

-1
find / -samefile file.txt -print

Найдет все ссылки на файл с тем же номером inode, что и file.txt

добавление -xdevфлага позволит избежать findпересечения границ устройства («точки монтирования»). (Но это, вероятно, приведет к тому, что ничего не будет найдено, если findон не запускается в каталоге на том же устройстве, что и file.txt)

Обратите внимание, что findможет сообщать о нескольких путях для одного объекта файловой системы, потому что Inode может быть связан более чем одной записью каталога, возможно, даже используя разные имена. Например:

find /bin -samefile /bin/gunzip -ls

Будет выводить:

12845178    4 -rwxr-xr-x   2 root     root         2251 feb  9  2012 /bin/uncompress
12845178    4 -rwxr-xr-x   2 root     root         2251 feb  9  2012 /bin/gunzip

-1

Это будет работать как для файла, так и для папки:

getAbsolutePath(){
    [[ -d $1 ]] && { cd "$1"; echo "$(pwd -P)"; } || 
    { cd "$(dirname "$1")" || exit 1; echo "$(pwd -P)/$(basename "$1")"; }
}


-1

Другая утилита Linux, которая делает эту работу:

fname <file>

-1

В Mac OS, если вы просто хотите получить путь к файлу в поисковике, управляйте щелчком файла и прокрутите вниз до «Службы» внизу. Вы получаете множество вариантов, включая «копировать путь» и «копировать полный путь». Нажатие на один из них помещает путь в буфер обмена.


-1

В Mac указанном ниже строке работает. Не нужно добавлять какие-либо необычные линии.

> pwd filename

6
Нет, он просто печатает рабочий каталог (без имени файла), как следует из названия командыprint working directory
anilbey

-2
fp () {
PHYS_DIR=`pwd -P`
RESULT=$PHYS_DIR/$1
echo $RESULT | pbcopy
echo $RESULT
}

Копирует текст в буфер обмена и отображает текст в окне терминала.

:)

(Я скопировал часть кода из другого ответа переполнения стека, но больше не могу найти этот ответ)


-2

самый простой способ, который я нашел, это

for i in `ls`; do echo "`pwd`/$i"; done

это хорошо работает для меня


-2

В Mac OSX выполните следующие действия:

  1. cd в каталог целевого файла.
  2. Введите одну из следующих команд терминала.
Терминал
ls "`pwd`/file.txt"
echo $(pwd)/file.txt
  1. Замените file.txtна ваше фактическое имя файла.
  2. Нажмите Enter

-3

Помимо "readlink -f", другая часто используемая команда:

$find  /the/long/path/but/I/can/use/TAB/to/auto/it/to/ -name myfile
/the/long/path/but/I/can/use/TAB/to/auto/it/to/myfile
$

Это также дает полный путь и имя файла в консоли

Не по теме: этот метод просто дает относительные ссылки, а не абсолютные. Команда readlink -fявляется правильной.


-3

Создайте функцию, подобную приведенной ниже (выводит абсолютный путь к файлу с помощью pwd и добавляет файл в конец пути:

abspath() { echo $(pwd "$1")/"$1"; }

Теперь вы можете просто найти любой путь к файлу:

abspath myfile.ext
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.