বাশ ডিরেক্টরিতে একটি পিতামাতার প্রাপ্ত


207

আমার কাছে যদি ফাইলের পথ থাকে যেমন ...

/home/smith/Desktop/Test
/home/smith/Desktop/Test/

আমি স্ট্রিংটি কীভাবে পরিবর্তন করব যাতে এটি প্যারেন্ট ডিরেক্টরি হবে?

যেমন

/home/smith/Desktop
/home/smith/Desktop/

4
আপনি কেবল ' ..' ব্যবহার করতে পারেন , তবে এটি সম্ভবত আপনার মনে ছিল না।
জোনাথন লেফলার

উত্তর:


331
dir=/home/smith/Desktop/Test
parentdir="$(dirname "$dir")"

সেখানেও যদি একটি পিছনে স্ল্যাশ থাকে তবে কাজ করে।


14
ভিতরে থাকা উদ্ধৃতিগুলি গুরুত্বপূর্ণ বা আপনি আপনার সমস্ত ডেটা আলগা করতে যাচ্ছেন
amp

10
এবং বর্তমান চলমান ডিরেক্টরিটির পিতামাতাকে পেতে আমি যে রূপটি ব্যবহার করছি: parentdir=$(dirname `pwd`)
TheGrimmScientist

3
দ্রষ্টব্য, এই পদ্ধতিটি "কুরুচিপূর্ণ" নামের জন্য নিরাপদ। "-Rm -rf" এর মতো একটি নাম পছন্দসই আচরণটি ভেঙে দেবে। সম্ভবত "।" হবে, খুব। যে যদি এটি সর্বোত্তম উপায় আমি জানি না, কিন্তু আমি একটি পৃথক তৈরি করেছি প্রশ্ন এখানে "শুদ্ধি শ্রেনীর": stackoverflow.com/questions/40700119/...
VasiliNovikov

4
ক্রিস্টোফার শ্রোবা হ্যাঁ, আমি উদ্ধৃতিগুলি বাদ দিয়েছিলাম এবং তারপরে আমার এইচডিডি আংশিকভাবে মুছে গেছে। কী ঘটেছে ঠিক তা আমি মনে করি না: সম্ভবত একটি অকাট্য হোয়াইটস্পিড ডিরেক্টরি সম্ভবত টার্গেটের পরিবর্তে পিতামাতারকে মুছে দেয় - আমার স্ক্রিপ্টটি স্রেফ / হোম / এক্সএক্সএক্স / ফোল্ডারটি মুছে ফেলেছে।
ক্যাটালফেটামাইন

3
ওহ ঠিক আছে, সুতরাং আপনি ইতিমধ্যে একটি মুছে ফেলা আদেশ কমান্ড না দিলে কমান্ড সম্পর্কে কোনও তথ্য নেই যা কোনও তথ্য হারিয়ে ফেলবে, তাই না? আপনি যে স্থানটির সাথে মহাকাশ চরিত্রের বিভক্ত হওয়া এবং প্রত্যাশার চেয়ে অনেক বেশি মুছে ফেলার চেষ্টা করছেন তা কেবলমাত্র একটি বিষয় ছিল?
ক্রিস্টোফার শ্রোবা 14


14

echo $(cd ../ && pwd)যে ডিরেক্টরিতে পিতামাতার দির আপনি এটি সন্ধান করতে চান সেখানে কাজ করার সময় কেবলমাত্র ব্যবহার করুন । এই চেইনটির পিছনে পিছনে স্ল্যাশ না থাকার অতিরিক্ত সুবিধা রয়েছে।


তোমার echoএখানে দরকার নেই
gniourf_gniourf

14

স্পষ্টতই পিতৃ ডিরেক্টরিটি ডট-ডট ফাইলের নাম যুক্ত করে দেওয়া হয়:

/home/smith/Desktop/Test/..     # unresolved path

তবে আপনাকে অবশ্যই সমাধানের পথটি (কোনও বিন্দু-বিন্দু পথের উপাদান ছাড়াই একটি নিখুঁত পাথ) চাইবেন :

/home/smith/Desktop             # resolved path

উপরের উত্তরগুলির সাথে ব্যবহার করা সমস্যাটি dirnameহ'ল আপনি যখন বিন্দু-বিন্দু দিয়ে কোনও পাথ প্রবেশ করেন তখন সেগুলি কাজ করে না:

$ dir=~/Library/../Desktop/../..
$ parentdir="$(dirname "$dir")"
$ echo $parentdir
/Users/username/Library/../Desktop/..   # not fully resolved

এটি আরও শক্তিশালী :

dir=/home/smith/Desktop/Test
parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`

আপনি এটি খাওয়াতে পারেন /home/smith/Desktop/Test/.., তবে আরও জটিল পথগুলি:

$ dir=~/Library/../Desktop/../..
$ parentdir=`eval "cd $dir;pwd;cd - > /dev/null"`
$ echo $parentdir
/Users                                  # the fully resolved path!

সম্পাদনা: যদি এটি কাজ না করে তবে পরীক্ষা করুন যে আপনার cdকোনও পরিবর্তন হয়নি, যেমনটি কখনও কখনও প্রচলিত অনুশীলন,

$ which cd
cd is a function  #cd was modified to print extra info, so use "builtin cd" to override
cd ()
{
    builtin cd "$@";
    ls -FGAhp
}
...

evalব্যবহারকারীর ইনপুটকে পার্স করার কোনও সম্ভাবনা থাকলে আপনার সিস্টেমের বিরুদ্ধে খারাপ জিনিসগুলি আশা বা চালানো আশা করে না এমন জায়গায় রাখে এমনটি ব্যবহার করা দুর্দান্ত নয়। আপনি কি pushd $dir 2>&1 >/dev/null && pwd && popd 2>&1 >/dev/nullপরিবর্তে ব্যবহার করতে পারেন eval?
ড্রাগন 788

2
আপনার মোটেই দরকার নেই eval: শুধু করুন parentdir=$(cd -- "$dir" && pwd)। যেহেতু cdরানটি একটি সাব-শেলের মধ্যে চলছে, সুতরাং cdআমরা যেখানে ছিলাম সেখানে ফিরে আসার দরকার নেই । হাইফেন দিয়ে --প্রসারণ $dirশুরু হলে এটি এখানে The &&শুধু প্রতিরোধ করা হয় parentdirযখন একটি খালি বিষয়বস্তু আছে cdsuceed নি।
gniourf_gniourf

8

অন্য উত্তরের জন্য প্রেরণা

আমি খুব সংক্ষিপ্ত, পরিষ্কার, গ্যারান্টিযুক্ত কোড পছন্দ করি। বোনাস পয়েন্ট যদি এটি কোনও বাহ্যিক প্রোগ্রাম না চালায়, যেহেতু আপনাকে বিপুল সংখ্যক এন্ট্রি প্রক্রিয়াকরণের প্রয়োজন হবে, এটি লক্ষণীয়ভাবে দ্রুত হবে।

নীতি

আপনার কী কী গ্যারান্টি রয়েছে সে সম্পর্কে নিশ্চিত নন, তাই যাইহোক অফার করুন।

আপনার যদি গ্যারান্টি থাকে তবে আপনি খুব সংক্ষিপ্ত কোড সহ এটি করতে পারেন। ধারণাটি হ'ল শেষ স্ল্যাশ এবং যা কিছু অনুসরণ করে তা কাটাতে ব্যাশ পাঠ্যের বিকল্প বৈশিষ্ট্যটি ব্যবহার করা।

মূল প্রশ্নের সাধারণ থেকে আরও জটিল ক্ষেত্রে উত্তর।

যদি কোনও গতি ছাড়াই পাথের গ্যারান্টি দেওয়া থাকে (ইন এবং আউট)

P=/home/smith/Desktop/Test ; echo "${P%/*}"
/home/smith/Desktop

পাথটি যদি ঠিক এক স্ল্যাশের সাথে শেষ হওয়ার গ্যারান্টিযুক্ত হয় (ইন এবং আউট)

P=/home/smith/Desktop/Test/ ; echo "${P%/*/}/"
/home/smith/Desktop/

যদি ইনপুট পাথ শূন্য বা একটি স্ল্যাশের সাথে শেষ হতে পারে (আরও নয়) এবং আপনি আউটপুট পাথ স্ল্যাশ ছাড়াই শেষ করতে চান

for P in \
    /home/smith/Desktop/Test \
    /home/smith/Desktop/Test/
do
    P_ENDNOSLASH="${P%/}" ; echo "${P_ENDNOSLASH%/*}"
done

/home/smith/Desktop
/home/smith/Desktop

যদি ইনপুট পাথটিতে অনেকগুলি বহির্মুখী স্ল্যাশ থাকতে পারে এবং আপনি আউটপুট পাথটি স্ল্যাশ ছাড়াই শেষ করতে চান

for P in \
    /home/smith/Desktop/Test \
    /home/smith/Desktop/Test/ \
    /home/smith///Desktop////Test// 
do
    P_NODUPSLASH="${P//\/*(\/)/\/}"
    P_ENDNOSLASH="${P_NODUPSLASH%%/}"
    echo "${P_ENDNOSLASH%/*}";   
done

/home/smith/Desktop
/home/smith/Desktop
/home/smith/Desktop

1
চমত্কার উত্তর। যেহেতু মনে হচ্ছে তিনি কোনও স্ক্রিপ্টের মধ্যে থেকে এটি করার জন্য কোনও উপায় সন্ধান করছেন (স্ক্রিপ্টটির বর্তমান ডিরেক্টরিটি এবং এটির পিতামাতার সন্ধান করুন এবং স্ক্রিপ্টটি যেখানে বাস করেন তার সাথে সম্পর্কিত কিছু করুন) এটি দুর্দান্ত উত্তর এবং আপনার আরও নিয়ন্ত্রণ থাকতে পারে কিনা ইনপুট একটি trailing স্ল্যাশ বা না প্যারামিটার সম্প্রসারণ ব্যবহার করে বিরুদ্ধে রয়েছে ${BASH_SOURCE[0]}যা স্ক্রিপ্ট সম্পূর্ণ পাথ হবে যদি এটা মাধ্যমে sourced হয় নি sourceবা .
ড্রাগন 788

7

আপনি /home/smith/Desktop/Test/../যদি চান তবে:

dirname 'path/to/child/dir'

যেমন এখানে দেখা ।


1
দুঃখিত, আমি ব্যাশ স্ক্রিপ্টের মতো বলতে চাইছি, আমার ফাইল পাথের সাথে একটি পরিবর্তনশীল রয়েছে
YTKColumba

সেই কোডটি চালানো আমাকে ত্রুটি দেয় bash: dirname 'Test': syntax error: invalid arithmetic operator (error token is "'Test'")। সংযুক্ত কোডটিও ভুল।
মাইকেল হফম্যান

শুধু চলমান চেষ্টা dirname Testডিরেক্টরি থেকে Testহয়।
জন Egeland

1

আপনার নিখুঁত পাথের প্রয়োজন কিনা তার উপর নির্ভর করে আপনি অতিরিক্ত পদক্ষেপ নিতে চাইতে পারেন:

child='/home/smith/Desktop/Test/'
parent=$(dirname "$child")
abs_parent=$(realpath "$parent")

0

এটা ব্যবহার কর : export MYVAR="$(dirname "$(dirname "$(dirname "$(dirname $PWD)")")")" আপনি চতুর্থ অভিভাবক ডিরেক্টরি চাইলে

export MYVAR="$(dirname "$(dirname "$(dirname $PWD)")")" আপনি যদি তৃতীয় অভিভাবক ডিরেক্টরি চান

export MYVAR="$(dirname "$(dirname $PWD)")" যদি আপনি ২ য় পিতামাতার ডিরেক্টরি চান


ধন্যবাদ! ঠিক আমি যা খুঁজছিলাম
জোসে আবারকা

0

কুরুচিপূর্ণ কিন্তু দক্ষ

function Parentdir()

{

local lookFor_ parent_ switch_ i_

lookFor_="$1"

#if it is not a file, we need the grand parent
[ -f "$lookFor_" ] || switch_="/.."

#length of search string
i_="${#lookFor_}"

#remove string one by one until it make sens for the system
while [ "$i_" -ge 0 ] && [ ! -d "${lookFor_:0:$i_}" ];
do
    let i_--
done

#get real path
parent_="$(realpath "${lookFor_:0:$i_}$switch_")" 

#done
echo "
lookFor_: $1
{lookFor_:0:$i_}: ${lookFor_:0:$i_}
realpath {lookFor_:0:$i_}: $(realpath ${lookFor_:0:$i_})
parent_: $parent_ 
"

}

    lookFor_: /home/Om Namah Shivaya
{lookFor_:0:6}: /home/
realpath {lookFor_:0:6}: /home
parent_: /home 


lookFor_: /var/log
{lookFor_:0:8}: /var/log
realpath {lookFor_:0:8}: /UNIONFS/var/log
parent_: /UNIONFS/var 


lookFor_: /var/log/
{lookFor_:0:9}: /var/log/
realpath {lookFor_:0:9}: /UNIONFS/var/log
parent_: /UNIONFS/var 


lookFor_: /tmp//res.log/..
{lookFor_:0:6}: /tmp//
realpath {lookFor_:0:6}: /tmp
parent_: / 


lookFor_: /media/sdc8/../sdc8/Debian_Master//a
{lookFor_:0:35}: /media/sdc8/../sdc8/Debian_Master//
realpath {lookFor_:0:35}: /media/sdc8/Debian_Master
parent_: /media/sdc8 


lookFor_: /media/sdc8//Debian_Master/../Debian_Master/a
{lookFor_:0:44}: /media/sdc8//Debian_Master/../Debian_Master/
realpath {lookFor_:0:44}: /media/sdc8/Debian_Master
parent_: /media/sdc8 


lookFor_: /media/sdc8/Debian_Master/../Debian_Master/For_Debian
{lookFor_:0:53}: /media/sdc8/Debian_Master/../Debian_Master/For_Debian
realpath {lookFor_:0:53}: /media/sdc8/Debian_Master/For_Debian
parent_: /media/sdc8/Debian_Master 


lookFor_: /tmp/../res.log
{lookFor_:0:8}: /tmp/../
realpath {lookFor_:0:8}: /
parent_: /

0

চার্লস ডাফি ধারণা / মন্তব্য থেকে শুরু হয়েছে - ডিসেম্বর 17 '14 5:32 এ বিষয়টিতে বাশ স্ক্রিপ্টে বর্তমান ডিরেক্টরি নাম (পুরো পথ ছাড়াই) পান

#!/bin/bash
#INFO : /programming/1371261/get-current-directory-name-without-full-path-in-a-bash-script
# comment : by Charles Duffy - Dec 17 '14 at 5:32
# at the beginning :



declare -a dirName[]

function getDirNames(){
dirNr="$(  IFS=/ read -r -a dirs <<<"${dirTree}"; printf '%s\n' "$((${#dirs[@]} - 1))"  )"

for(( cnt=0 ; cnt < ${dirNr} ; cnt++))
  do
      dirName[$cnt]="$( IFS=/ read -r -a dirs <<<"$PWD"; printf '%s\n' "${dirs[${#dirs[@]} - $(( $cnt+1))]}"  )"
      #information – feedback
      echo "$cnt :  ${dirName[$cnt]}"
  done
}

dirTree=$PWD;
getDirNames;

0

যদি কোন কারনের জন্য আপনাকে ডিরেক্টরি একটি নির্দিষ্ট সংখ্যা নেভিগেট আগ্রহী আপনার কাছে যেত না: nth_path=$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd ../../../ && pwd)। এটি 3 পিতামাতার ডিরেক্টরি আপ দেবে


ler BASH_SOURCE [0] why সরল simp BASH_SOURCE এর পরিবর্তে
নাম জি ভিউ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.