it-swarm.dev

كيف يمكنني الحصول على الدليل؟

لقد كتبت نص باش يأخذ ملف إدخال كحجة ويقرأه.
يحتوي هذا الملف على بعض المسارات (نسبة إلى موقعه) إلى الملفات الإضافية المستخدمة.

أود أن ينتقل البرنامج النصي إلى المجلد الذي يحتوي على ملف الإدخال ، لتنفيذ أوامر أخرى.

لذلك ، كيف يمكنني الحصول على المجلد (والمجلد فقط) من ملف الإدخال؟ (في لينكس.)

68
BobMcGee

للحصول على استخدام المسار الكامل:

readlink -f relative/path/to/file

للحصول على دليل ملف:

dirname relative/path/to/file

يمكنك أيضًا الجمع بين الاثنين:

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

إذا لم يكن readlink -f متاحًا على نظامك ، فيمكنك استخدام هذا:

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

لاحظ أنه إذا كنت بحاجة فقط إلى الانتقال إلى دليل لملف محدد كمسار نسبي ، فلست بحاجة إلى معرفة المسار المطلق ، والمسار النسبي قانوني تمامًا ، لذلك استخدم فقط:

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

إذا كنت ترغب في العودة (أثناء تشغيل البرنامج النصي) إلى المسار الأصلي ، فاستخدم pushd بدلاً من cd ، و popd عند الانتهاء.

131
Chen Levy

ألقِ نظرة على صفحة "الرجل" لـ realpath ، وأنا أستخدم ذلك وشيء من هذا القبيل:

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

للقيام بما يبدو أنك تحاول القيام به.

18
Richard Sitze

سيعمل هذا مع كل من الملف والمجلد:

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

بعض التفسيرات:

  1. الحصول على هذا البرنامج النصي المسار النسبي كوسيطة "$1"
  2. ثم نحصل على dirname جزء من هذا المسار (يمكنك تمرير إما ملف أو ملف إلى هذا البرنامج النصي): dirname "$1"
  3. ثم cd "$(dirname "$1"); في هذا دير النسبية
  4. pwd -P واحصل على المسار المطلق. سيتجنب خيار -P الارتباطات
  5. كخطوة أخيرة نحن echo ذلك

ثم قم بتشغيل البرنامج النصي الخاص بك:

abs.sh your_file.txt
3
Eugen Konkov

جرب منتج مكتبة Bash الجديد realpath-lib أكثر في GitHub الذي قدمناه للمجتمع للاستخدام المجاني وغير المرتبط به. إنها نظيفة وبسيطة وموثقة جيدًا ، لذلك من الرائع أن نتعلم منها. يمكنك ان تفعل:

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

هذه الوظيفة هي جوهر المكتبة:

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

}

إنه Bash 4+ ، ولا يتطلب أي تبعيات ويوفر أيضًا get_dirname و get_filename و get_stemname و validate_path.

1
AsymLabs

تأتي مشكلة الإجابة أعلاه مع إدخال الملفات مع ". /" مثل "./my-file.txt"

الحل البديل (للكثير):

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