He escrito un script bash que toma un archivo de entrada como argumento y lo lee.
Este archivo contiene algunas rutas (relativas a su ubicación) a archivos adicionales utilizados.
Me gustaría que el script vaya a la carpeta que contiene el archivo de entrada para ejecutar más comandos.
Entonces, ¿cómo obtengo la carpeta (y solo la carpeta) de un archivo de entrada? (En linux.)
Respuestas:
Para obtener el uso de la ruta completa:
Para obtener el directorio de un archivo:
También puedes combinar los dos:
Si
readlink -f
no está disponible en su sistema, puede usar esto * :function myreadlink() { ( cd "$(dirname $1)" # or cd "${1%/*}" echo "$PWD/$(basename $1)" # or echo "$PWD/${1##*/}" ) }
Tenga en cuenta que si solo necesita moverse a un directorio de un archivo especificado como una ruta relativa, no necesita saber la ruta absoluta, una ruta relativa es perfectamente legal, así que use:
cd $(dirname relative/path/to/file)
si desea volver (mientras se ejecuta el script) a la ruta original, utilice en
pushd
lugar decd
ypopd
cuando haya terminado.* Si bien lo
myreadlink
anterior es suficientemente bueno en el contexto de esta pregunta, tiene algunas limitaciones en relación con lareadlink
herramienta sugerida anteriormente. Por ejemplo, no sigue correctamente un enlace a un archivo con diferentebasename
.fuente
readlink -f
, lamentablemente, no funciona en OS X.brew install coreutils
conseguirlo. stackoverflow.com/a/4031502/1022967 .${1%/*}
o${1##*/}
como sustitutos dedirname
ybasename
. El primero se rompe si le da un nombre de archivo simple (dirname foo.bar
sería, correctamente, ser.
), y el segundo se rompe para un directorio que termina con una barra (basename /foo/bar/
, correctamente, seríabar
).basename
/dirname
no son incorporados), y lo verán funcionando al principio, pero de repente se romperá en algún momento en el futuro por aparentemente no ser bueno razón. Evitaría sugerirlo como una opción, o negaría que realmente no sea un sustituto a prueba de balas.Eche un vistazo a la página de manual de
realpath
, yo uso eso y algo como:para hacer lo que parece que estás intentando hacer.
fuente
Esto funcionará tanto para el archivo como para la carpeta:
absPath(){ if [[ -d "$1" ]]; then cd "$1" echo "$(pwd -P)" else cd "$(dirname "$1")" echo "$(pwd -P)/$(basename "$1")" fi }
fuente
$cat abs.sh #!/bin/bash echo "$(cd "$(dirname "$1")"; pwd -P)"
Algunas explicaciones:
"$1"
dirname "$1"
cd "$(dirname "$1");
en este directorio relativopwd -P
y obtener la ruta absoluta. La-P
opción evitará los enlaces simbólicosecho
loLuego ejecuta tu script:
fuente
Pruebe nuestro nuevo producto de biblioteca Bash, realpath-lib, en GitHub, que le hemos proporcionado a la comunidad de forma gratuita y sin obstáculos. Es limpio, simple y bien documentado, por lo que es genial aprender de él. Tu puedes hacer:
get_realpath <absolute|relative|symlink|local file path>
Esta función es el núcleo de la biblioteca:
if [[ -f "$1" ]] then # file *must* exist if cd "$(echo "${1%/*}")" &>/dev/null then # file *may* not be local # exception is ./file.ext # try 'cd .; cd -;' *works!* local tmppwd="$PWD" cd - &>/dev/null else # file *must* be local local tmppwd="$PWD" fi else # file *cannot* exist return 1 # failure fi # reassemble realpath echo "$tmppwd"/"${1##*/}" return 0 # success }
Es Bash 4+, no requiere ninguna dependencia y también proporciona get_dirname, get_filename, get_stemname y validate_path.
fuente
El problema con la respuesta anterior viene con la entrada de archivos con "./" como "./my-file.txt"
Solución alternativa (de muchas):
myfile="./somefile.txt" FOLDER="$(dirname $(readlink -f "${ARG}"))" echo ${FOLDER}
fuente
He estado usando readlink -f funciona en linux
entonces
FULL_PATH=$(readlink -f filename) DIR=$(dirname $FULL_PATH) PWD=$(pwd) cd $DIR #<do more work> cd $PWD
fuente
PWD
ya existe en Bash y su valor es en realidad el directorio actual? Y use más citas también.