Как получить абсолютный каталог файла в bash?


Я написал сценарий bash, который принимает входной файл в качестве аргумента и читает его.
Этот файл содержит некоторые пути (относительно его расположения) к дополнительным файлам, используемым.

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

и как мне получить папку (и только папку) из входного файла? (в linux.)

7 63

7 ответов:

чтобы получить полный путь:

readlink -f relative/path/to/file

чтобы получить каталог файла:

dirname relative/path/to/file

вы также можете объединить два:

dirname $(readlink -f relative/path/to/file)

если readlink -f недоступно в вашей системе вы можете использовать это:

function myreadlink() {
  (
  cd $(dirname )         # or  cd ${1%/*}
  echo $PWD/$(basename ) # or  echo $PWD/${1##*/}
  )
}

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

cd $(dirname relative/path/to/file)

если вы желаете вернитесь (пока скрипт работает) к исходному пути, используйте pushd вместо cd и popd когда вы сделали.

взгляните на man-странице realpath, Я использую это и как-то так:

CONTAININGDIR=$(realpath ${FILEPATH%/*})

делать то, что кажется, что вы пытаетесь сделать.

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

absPath(){
    if [[ -d "" ]]; then
        cd ""
        echo "$(pwd -P)"
    else 
        cd "$(dirname "")"
        echo "$(pwd -P)/$(basename "")"
    fi
}
$cat abs.sh
#!/bin/bash
echo "$(cd "$(dirname "")"; pwd -P)"

некоторые пояснения:

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

затем запустите ваш сценарий:

abs.sh your_file.txt

попробуйте наш новый продукт библиотеки Bash realpath-lib на GitHub, что мы дали сообществу для свободного и беспрепятственного использования. Это чистый, простой и хорошо документирован, так что это здорово учиться. Вы можете сделать:

get_realpath <absolute|relative|symlink|local file path>

эта функция является ядром библиотеки:

if [[ -f "" ]]
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

}

Это Bash 4+, не требует каких-либо зависимостей, а также предоставляет get_dirname, get_filename, get_stemname и validate_path.

Я использую readlink-f работает на linux

так

FULL_PATH=$(readlink -f filename)
DIR=$(dirname $FULL_PATH)

PWD=$(pwd)

cd $DIR

#<do more work>

cd $PWD

проблема с приведенным выше ответом поставляется с файлами ввода с "./ "нравится"./мой файл.txt"

обходной путь (из многих):

    myfile="./somefile.txt"
    FOLDER="$(dirname $(readlink -f "${ARG}"))"
    echo ${FOLDER}