Como obter o caminho completo de um arquivo?


717

Existe uma maneira fácil de imprimir o caminho completo file.txt?

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

o <command>

dir> <command> file.txt  

deve imprimir

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

Respostas:


1189

Use o readlink :

readlink -f file.txt

32
É para isso que serve '-f'.
filmor


5
Apenas testado em 10.9.2, funciona bem. que readlink / usr / local / opt / coreutils / libexec / gnubin / readlink readlink --version readlink (coreutils GNU) 8,22
J0hnG4lt

10
@ J0hnG4lt: isso porque você instalou o coreutils com homebrew e alterou seu PATH para apontar para os binários não corrigidos. Instalar coreutils, deixar o PATH sozinho e usar o "greadlink" também funcionaria.
Tim Smith

35
no MAC: instalar homebrew, em seguida, brew install coreutilsem seguida,greadlink -f file.txt
Para Kra

217

Suponho que você esteja usando Linux.

Encontrei um utilitário chamado realpathcoreutils 8.15.

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

Conforme os comentários @ styrofoam-fly e @ arch-standton, por realpathsi só não verifica a existência do arquivo, para resolver isso, adicione o eargumento:realpath -e file


Funciona com cygwin (com mintty 2.7.9)
Scrambo

1
realpathestava comprometido com as coreutils repo final de 2011, a liberação 8,15 foi feito em janeiro de 2012, respondi a pergunta (com a readlinksugestão) março 2011 :)
filmor

2
realpath não verifica a existência do arquivo, apenas resolve os caminhos. Pedir um caminho completo de um arquivo não existente deve resultar em um erro.
styrofoam fly

4
@styrofoamfly realpath -eimprime um erro se o argumento não existir.
Arch Stanton

76

O seguinte geralmente faz o truque:

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

Olá. Achei esta resposta melhor para minha exigência. Você pode explicar como eu posso usar uma variável local em vez do parâmetro de linha de comando (ou seja, $ 1)
Deej

1
LOCAL_VARIABLE="filename.txt" && echo $(cd $(dirname "$LOCAL_VARIABLE") && pwd -P)/$(basename "$LOCAL_VARIABLE")
precisa saber é o seguinte

7
@SopalajodeArrierez Como readlinknão funciona se o arquivo for um link simbólico, ele mostrará o destino do link simbólico em vez do próprio link simbólico.
Qwertzguy

1
Eu gosto disso, porque readlinkme leva de volta ao diretório pai de onde o link simbólico gera, mas isso o ignora.
Sukhi 26/05

set .. && echo $(cd $(dirname "$1") && pwd -P)/$(basename "$1") ### saída: / home / Ravi / ..
Tom Hale

35

Eu sei que há uma maneira mais fácil disso, mas que se dane se eu puder encontrar ...

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"

ou

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

1
Para mim, no Mac, isso funcionou - em vez de $ pwd -find `pwd` -type file -name \*.dmp
mrwaim

14

Se você estiver no mesmo diretório que o arquivo:

ls "`pwd`/file.txt"

Substitua file.txtpelo nome do arquivo de destino.


9
você também pode fazerecho $(pwd)/file.txt
Alex

12

No Windows:

  • Manter Shiftpressionado e clicar com o botão direito do mouse em um arquivo no Windows Explorer fornece uma opção chamada Copy as Path. Isso copiará o caminho completo do arquivo para a área de transferência.

No Linux:

  • Você pode usar o comando realpath yourfilepara obter o caminho completo de um arquivo, conforme sugerido por outras pessoas.


4

Funciona em Mac, Linux, * nix:

Isso fornecerá um csv citado de todos os arquivos no diretório atual:

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

A saída disso pode ser facilmente copiada em uma lista python ou em qualquer estrutura de dados semelhante.


imprime o caminho pwd atual
Sand1512

Sim, os caminhos completos separados por vírgula para todos os arquivos em pwd, para um arquivo, basta fazer ls 'filename' em vez de apenas 'ls'.
Bhargav Srinivasan

3

Você pode usar o script fpn (nome completo do caminho) :

% 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

fpnnão é um pacote padrão do Linux, mas é um projeto gratuito e aberto do github e você pode configurá-lo em um minuto .


1
Geralmente, pwdpor si só, deve funcionar bem no Linux e na maioria dos outros ambientes de sistema operacional tipo Unix.
karolus

3

Você pode usar esta função. Se o nome do arquivo for fornecido sem o caminho relativo, presume-se que ele esteja presente no diretório de trabalho atual:

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

Uso:

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

Uso com caminho relativo:

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

Com espaços no nome do arquivo:

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

2

Em um cenário semelhante, estou lançando um script cshell de outro local. Para definir o caminho absoluto correto do script para que seja executado apenas no diretório designado, estou usando o seguinte código:

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

$0 armazena a string exata de como o script foi executado.

Por exemplo, se o script foi lançado como este: $> ../../test/test.csh, $script_dirconterá/home/abc/sandbox/v1/../../test


votou a favor, pois este é o mais fácil e mais relevante. No entanto, se você digitar ./test.csh, terá um caminho que termina com/test/.
vinyll

2

No Mac OS X, substituí os utilitários que acompanham o sistema operacional e os substitui por uma versão mais recente do coreutils. Isso permite acessar ferramentas como readlink -f(para o caminho absoluto dos arquivos) e realpath(caminho absoluto dos diretórios) no seu Mac.

A versão Homebrew acrescenta um 'G' (para GNU Tools) na frente do nome do comando - para que os equivalentes se tornem greadlink -f FILEe grealpath DIRECTORY.

Instruções para instalar as ferramentas coreutils / GNU no Mac OS X através do Homebrew podem ser encontradas neste artigo do StackExchange .

Nota: Os comandos readlink -fe realpathdevem funcionar imediatamente para usuários que não sejam Mac Unix.


2
brew install coreutils
Para Kra

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

Esta é uma explicação do que está acontecendo na resposta de @ ZeRemz :

  1. Este script obtém o caminho relativo como argumento "$1"
  2. Em seguida, obtemos parte dirname desse caminho (você pode passar dir ou arquivo para este script):dirname "$1"
  3. Então nós cd "$(dirname "$1")entramos nesse diretório relativo
  4. && pwd -Pe obtenha um caminho absoluto para isso. -Popção evitará todos os links simbólicos
  5. Depois disso, anexamos o nome da base ao caminho absoluto:$(basename "$1")
  6. Como etapa final, echoele

1

Isso funcionou muito bem para mim. Ele não depende do sistema de arquivos (um profissional / con, dependendo da necessidade), por isso será rápido; e, deve ser portátil para a maioria dos * NIX. Ele assume que a sequência passada é realmente relativa ao PWD e não a outro diretório.

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

Isso é ingênuo, mas eu precisava torná-lo compatível com POSIX. Requer permissão para cd no diretório do arquivo.

#!/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

Usualmente:

find `pwd` | grep <filename>

Como alternativa, apenas para a pasta atual:

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

hm por que o ódio?
sjas

0

Gosto de muitas das respostas já fornecidas, mas achei isso realmente útil, especialmente em um script, para obter o caminho completo de um arquivo, incluindo os links simbólicos e as referências relativas, como .e..

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

O que retornará o caminho completo do a filepartir do caminho raiz. Isso pode ser usado em um script para que o script saiba de qual caminho está sendo executado, o que é útil em um clone de repositório que pode estar localizado em qualquer lugar da máquina.

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

Posso então usar a ${basePath}variável nos meus scripts para referenciar diretamente outros scripts.

Espero que isto ajude,

Dave


0

Você pode salvar isso no seu shell.rcou simplesmente colocar no console

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

exemplo:

ap somefile.txt

irá produzir

/home/user/somefile.txt

3
Mas então ap ../foobar.txtvai dar /home/user/../foobar.txt, o que geralmente não é o que você deseja.
bdesham

2
Também ap /tmp/foobar.txtvai dar /home/user//tmp/foobar.txt, o que está errado.
David Given

-1
find / -samefile file.txt -print

Encontrará todos os links para o arquivo com o mesmo número de inode que o arquivo.txt

adicionar um -xdevsinalizador evitará findcruzar os limites do dispositivo ("pontos de montagem"). (Mas isso provavelmente não fará com que nada seja encontrado se o findarquivo não iniciar em um diretório no mesmo dispositivo que file.txt)

Observe que findpode relatar vários caminhos para um único objeto do sistema de arquivos, porque um Inode pode ser vinculado por mais de uma entrada de diretório, possivelmente até usando nomes diferentes. Por exemplo:

find /bin -samefile /bin/gunzip -ls

Saída:

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

Isso funcionará para arquivos e pastas:

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


-1

Outro utilitário Linux, que faz este trabalho:

fname <file>

-1

No Mac OS, se você deseja apenas localizar o caminho de um arquivo no localizador, clique com o botão direito no arquivo e role para baixo até "Serviços" na parte inferior. Você tem muitas opções, incluindo "caminho da cópia" e "caminho completo da cópia". Clicar em um deles coloca o caminho na área de transferência.


-1

No mac mencionado abaixo a linha funciona. Não há necessidade de adicionar linhas sofisticadas.

> pwd filename

6
Sem ele só imprime o diretório de trabalho (sem o nome do arquivo) como o nome do comando sugereprint working directory
anilbey

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

Copia o texto para a área de transferência e exibe o texto na janela do terminal.

:)

(Copiei parte do código de outra resposta de estouro de pilha, mas não consigo mais encontrá-la)


-2

a maneira mais fácil que encontrei é

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

funciona bem para mim


-2

No Mac OSX, execute as seguintes etapas:

  1. cd no diretório do arquivo de destino.
  2. Digite um dos seguintes comandos do terminal.
terminal
ls "`pwd`/file.txt"
echo $(pwd)/file.txt
  1. Substitua file.txtpelo seu nome de arquivo real.
  2. pressione Enter

-3

Ao lado de "readlink -f", outro comando comumente usado:

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

Isso também fornece o caminho completo e o nome do arquivo no console

Fora do tópico: esse método fornece apenas links relativos , não absolutos. O readlink -fcomando é o correto.


-3

Crie uma função como a abaixo (ecoa o caminho absoluto de um arquivo com pwd e adiciona o arquivo no final do caminho:

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

Agora você pode encontrar qualquer caminho de arquivo:

abspath myfile.ext
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.