Come ottenere il percorso completo di un file in bash?


22

Vorrei un modo semplice per ottenere il percorso completo di un file. Attualmente scrivo questo:

echo `pwd`/file.ext

Cercando di accorciarlo, ho creato un alias bash:

alias fp='echo `pwd`/'

Ma ora se scrivo fp file.ext, c'è uno spazio che appare tra il /e il file.ext.

Esiste già un comando del genere e me lo manca? In caso contrario, come potrei fare per creare un tale alias o una funzione in bash?

Risposte:


30

Sui sistemi Linux, dovresti avere readlinkinstallato il progetto coreutils GNU e puoi farlo:

readlink -f file.ext

Sui sistemi Debian / Ubuntu potrebbe essere installata l'utility realpath che "fornisce principalmente le stesse funzionalità /bin/readlink -fdel pacchetto coreutils".


readlink -f(o realpath, che è un'utilità precedente conservata per la compatibilità) espanderà ulteriormente tutti i collegamenti simbolici, il che non è necessariamente desiderabile.
Gilles 'SO- smetti di essere malvagio' il

8
a proposito: non funziona su macosx.
Akira,

Sul mio mac, ho installato coreutils usando homebrew e include realpath.
Doug Harris,

7

Invece del pwdcomando, usa la PWDvariabile (è anche in POSIX):

fp () {
  case "$1" in
    /*) printf '%s\n' "$1";;
    *) printf '%s\n' "$PWD/$1";;
  esac
}

Se è necessario supportare Windows, il riconoscimento dei percorsi assoluti sarà più complicato poiché ogni porta degli strumenti unix ha le proprie regole per la traduzione dei percorsi dei file. Con Cygwin, utilizzare l' cygpathutilità.


Forse è una tua scelta, ma questa funzione non emetterà la nuova riga.
cYrus

questo approccio ha il vantaggio di usare solo shell incorporate, che è più veloce che chiamare binari esterni. dovresti rendere questo fatto un po 'più chiaro.
Akira,

4

per rispondere alla tua domanda con quello che usi adesso:

l'alias si espande nella posizione in cui stai digitando in questo momento. hai digitato:

% fp<SPACE>file.ext

questo diventa

% echo `pwd`<SPACE>file.exe

potresti usare una funzione per evitare che:

function fp() {
    echo `pwd`/"$1"
}

puoi usarlo come al solito:

% fp file.ext

Hai bisogno di virgolette doppie per la sostituzione di variabili e comandi:echo "`pwd`/$1"
SO di Gilles

@Gilles: in quali circostanze?
Akira,

2
@akira: usa sempre virgolette doppie a meno che tu non voglia che il risultato dell'espansione sia trattato come un modello di globbing e che i risultati del globbing siano divisi in parole. Qui stai costruendo un singolo nome di file, quindi sono necessarie le doppie virgolette (prova la tua funzione con un file chiamato *in una directory contenente altri file).
Gilles 'SO- smetti di essere malvagio'

il ' ' è disturbato dalla shell (zsh nel mio caso) ed espanso prima che colpiscano la funzione. fp *produce /tmp/4cc3ea0c1b34bpoiché questo è il primo parametro per la funzione. gli altri parametri sarebbero gli altri file nella directory. non appena ho un file chiamato ' ' la funzione funziona ancora come previsto, chiamandola con "*" o * o *
Akira

bash è il "cattivo" qui come sembra, bash produce ciò a cui ti riferisci.
Akira,

3

Puoi usare:

realpath file.ext

Non ho quello. Da dove viene?
frabjous,

@frabjous: è specifico per Debian e derivati ​​e verrà installato solo se lo hai richiesto o un pacchetto dipende da esso.
Gilles 'SO- smetti di essere malvagio' il

Sto usando Arch. Non è basato su Debian, ma c'è comunque un pacchetto in AUR. Non sono sicuro che valga la pena installarlo se ho già readlink.
frabjous,

Bene, questa è un'opzione; oppure puoi considerare una funzione, vedi la risposta di Gilles . Comunque dipende dall'uso reale che vuoi fare (sono curioso).
cYrus

@frabjous: Non hai specificato su quale sistema sei, ma se utilizza un gestore di pacchetti basato su Aptitude (Debian, Ubuntu, Mint, ecc.), puoi digitare apt-cache search realpathper rivelare che i coreutils e i semplici pacchetti realpath entrambi lo contengono. È quindi possibile digitare sudo apt-get install realpath(o coreutils) per installarlo.
Michael Scheper,

1

Da /programming//a/3915420/5795941

Questo è l'unico modo accettabile per me. Non espande collegamenti come realpath e readlink ed è il modo classico di farlo che ho visto dappertutto.

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.