Як отримати повний шлях до файлу?


717

Чи є простий спосіб я надрукувати повний шлях file.txt?

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

The <command>

dir> <command> file.txt  

слід надрукувати

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

Відповіді:


1187

Використовувати readlink :

readlink -f file.txt

32
Ось для чого «-f».
фільм


5
Щойно перевірена 10.9.2, працює чудово. який readlink / usr / local / opt / coreutils / libexec / gnubin / readlink readlink - перетворення readlink (GNU coreutils) 8.22
J0hnG4lt

10
@ J0hnG4lt: це тому, що ви встановили coreutils з домашньою мовою та змінили свій PATH, щоб вказати на нефіксовані бінарні файли. Встановлення coreutils, залишити PATH в спокої і використовувати "greadlink" також буде добре.
Тім Сміт

35
на MAC: встановіть домашню мову, а brew install coreutilsпотімgreadlink -f file.txt
до

217

Я думаю, ви використовуєте Linux.

Я знайшов утиліту, яка називається realpathв coreutils 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 (з м'ятою 2.7.9)
Scrambo

1
realpathбуло скоєно до Coreutils repo в кінці 2011 року, реліз 8.15 було зроблено в січні 2012 року, я відповів на питання (з readlinkпропозицією) в березні 2011 року :)
фільм

2
realpath не перевіряє наявність файлу, він просто вирішує шляхи. Прохання про повний шлях неіснуючого файлу повинно призвести до помилки.
пінопласт летить

4
@styrofoamfly realpath -eвиводить помилку, якщо аргумент не існує.
Арк Стентон

76

Зазвичай, це робить трюк:

 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повертає мене до батьківського dir, звідки породжується символічне посилання, але це ігнорує його.
Сухі

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
Ця відповідь занадто конкретна, в ОП не йдеться про пошук команд.
AL

4

Працює на Mac, Linux, * nix:

Це дасть вам цитований csv всіх файлів у поточному режимі:

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

Результати цього можуть бути легко скопійовані в список пітонів або будь-яку подібну структуру даних.


друкує поточний шлях pwd
Sand1512,

Так, розділені комами повні шляхи для всіх файлів у pwd, для файлу просто зробіть ls 'ім'я файлу', а не просто '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.
carolus

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 на Mac OS X через Homebrew можна знайти в цьому аркуші StackExchange .

Примітка: Команди readlink -fта realpathкоманди повинні працювати з поля для користувачів, що не є Mac Mac Unix.


2
brew install coreutils
До Кра

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

Це пояснення того , що відбувається на @ ZeRemz в відповідь :

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

1

Це спрацювало досить добре для мене. Він не покладається на файлову систему (про / кон, залежно від потреби), тому він буде швидким; і, він повинен бути переносним для більшості будь-якого * 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. Потрібен дозвіл на компакт-диск у каталог файлу.

#!/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, якщо ви просто хочете отримати шлях до файлу у пошуку, натисніть на файл та прокрутіть униз до "Послуги" внизу. Ви отримуєте багато варіантів, включаючи "копіювати шлях" та "копіювати повний шлях". Клацання по одній із них ставить шлях до буфера обміну.


-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.