আপেক্ষিক পথ প্রদত্ত পরম পথটি পুনরুদ্ধার করার জন্য কোন আদেশ আছে?
উদাহরণস্বরূপ আমি want লাইনটি dir প্রতিটি ফাইলের পরম পথ থাকতে চাই to ./etc/
find ./ -type f | while read line; do
echo $line
done
আপেক্ষিক পথ প্রদত্ত পরম পথটি পুনরুদ্ধার করার জন্য কোন আদেশ আছে?
উদাহরণস্বরূপ আমি want লাইনটি dir প্রতিটি ফাইলের পরম পথ থাকতে চাই to ./etc/
find ./ -type f | while read line; do
echo $line
done
উত্তর:
ব্যবহার করুন:
find "$(pwd)"/ -type f
সমস্ত ফাইল পেতে বা
echo "$(pwd)/$line"
সম্পূর্ণ পাথ প্রদর্শন করতে (যদি আপেক্ষিক পথটি গুরুত্বপূর্ণ)
$(pwd)জায়গায় ব্যবহার $PWD? (হ্যাঁ, আমি জানি pwdএকটি বিল্টিন)
ব্যবহার করে দেখুন realpath।
~ $ sudo apt-get install realpath # may already be installed
~ $ realpath .bashrc
/home/username/.bashrc
সিমলিঙ্কগুলি প্রসারিত এড়াতে, ব্যবহার করুন realpath -s।
উত্তরটি " ফাইলের জন্য পরম পাথ মুদ্রণের জন্য বাশ / ফিশ কমান্ড " থেকে আসে ।
realpathম্যাকটিতে উপলব্ধ বলে মনে হচ্ছে না (ওএস এক্স 10.11 "এল ক্যাপিটান")। :-(
realpathমনে হয় না যে এটি
brew install coreutilsআনতে হবেrealpath
realpathএ ইতিমধ্যে উপস্থিত রয়েছে। আমার এটি আলাদাভাবে ইনস্টল করতে হবে না।
realpathউইন্ডোজের জন্য গিটে পাওয়া যায় (আমার পক্ষে, কমপক্ষে)।
আপনার যদি কোরিউটিলস প্যাকেজটি ইনস্টল করা থাকে তবে আপনি সাধারণত নিখুঁতটি readlink -f relative_file_nameপুনরুদ্ধার করতে ব্যবহার করতে পারেন (সমস্ত প্রতিলিপি সমাধানের সাথে)
brew install coreutils। তবে এক্সিকিউটেবলটি এ.জি. দ্বারা চালিত হয়:greadlink -f relative_file_name
#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
UPD কিছু ব্যাখ্যা
"$1"dirname "$1"cd "$(dirname "$1")এই আপেক্ষিক dir এর মধ্যে প্রবেশ করি এবং pwdশেল কমান্ড চালিয়ে এর জন্য পরম পথ পাবো$(basename "$1")echoএটাrealpathবা করার সমান নয় readlink -f। উদাহরণস্বরূপ, এটি এমন পাথগুলিতে কাজ করে না যেখানে শেষ উপাদানটি একটি সিমলিংক।
-Pদেওয়ার বিকল্পটি প্রদান করতে পারেন pwd:echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"
এর মূল্য কী, তার জন্য আমি যে উত্তরটি নেওয়া হয়েছিল তার পক্ষে ভোট দিয়েছি, তবে একটি সমাধান ভাগ করে নিতে চাই। ক্ষতিটি হ'ল এটি কেবল লিনাক্স - স্ট্যাক ওভারফ্লোতে আসার আগে আমি প্রায় 5 মিনিট ওএসএক্সের সমতুল্য খুঁজতে চেষ্টা করেছিলাম। আমি নিশ্চিত যে এটি বাইরে আছে।
লিনাক্স উপর আপনি ব্যবহার করতে পারেন readlink -eটমটম dirname।
$(dirname $(readlink -e ../../../../etc/passwd))
উৎপাদনের
/etc/
এবং তারপরে আপনি কেবল ফাইলের নাম পেতে dirname, basenameআপনার বোন ব্যবহার করেন
$(basename ../../../../../passwd)
উৎপাদনের
passwd
সব একসাথে রাখুন ..
F=../../../../../etc/passwd
echo "$(dirname $(readlink -e $F))/$(basename $F)"
উৎপাদনের
/etc/passwd
আপনি যদি নিরাপদে কোনও ডিরেক্টরিকে লক্ষ্য করে থাকেন তবে basenameকিছুই ফেরত পাবেন না এবং আপনি চূড়ান্ত আউটপুটটিতে ডাবল স্ল্যাশ দিয়ে শেষ করবেন।
dirname, readlinkএবং basename। এটি আমাকে প্রতীকী লিঙ্কের নিখুঁত পথ পেতে সহায়তা করেছে - এটির লক্ষ্য নয়।
/home/GKFXএবং আমি টাইপ করি touch newfile, তবে আমি এন্টার টিপানোর আগে আপনি কাজ করতে পারবেন যে আমি বোঝাতে চাইছি "create / home / GKFX / newfile", যা এখনও উপস্থিত নেই এমন একটি ফাইলের পরম পথ।
আমি মনে করি এটি সবচেয়ে বহনযোগ্য:
abspath() {
cd "$(dirname "$1")"
printf "%s/%s\n" "$(pwd)" "$(basename "$1")"
cd "$OLDPWD"
}
যদিও পথটি না থাকলে এটি ব্যর্থ হবে।
dirnameএটি একটি জিএনইউ কোর ইউটিলিটি, আমি বিশ্বাস করি এমন সব ইউনিক্সের পক্ষে সাধারণ নয়।
dirnameএকটি পসিক্স স্ট্যান্ডার্ড ইউটিলিটি, এখানে দেখুন: pubs.opengroup.org/onlinepubs/9699919799/utilities/dirname.html
${1##*/}এখন এক দিনের জন্য যে সংস্করণটি ব্যবহার করে তা ঠিক করার চেষ্টা করেছি এবং এখন আমি যে আবর্জনাটিকে এর সাথে প্রতিস্থাপন করেছি basename "$1"তা অবশেষে মনে হচ্ছে / / এ শেষ হওয়া পথগুলি সঠিকভাবে পরিচালনা করছে।
../..
realpath সম্ভবত সেরা
তবে ...
প্রাথমিক প্রশ্নটি শুরু করার জন্য খুব বিভ্রান্ত হয়েছিল, যেমনটি বলা হয়েছে যেভাবে প্রশ্নের সাথে খারাপ সম্পর্কিত নয় example
নির্বাচিত উত্তরটি প্রকৃতপক্ষে প্রদত্ত উদাহরণটির উত্তর দেয়, এবং শিরোনামের কোনও প্রশ্নেই নয়। প্রথম আদেশটি হ'ল উত্তর (এটি কি সত্য? আমি সন্দেহ করি), এবং '/' ছাড়াই এটি করতে পারত। এবং দ্বিতীয় কমান্ডটি কি করছে তা দেখতে আমি ব্যর্থ।
বেশ কয়েকটি ইস্যু মিশ্রিত:
একটি আপেক্ষিক পথের নামকে পরম স্থানে পরিবর্তন করা, এটি যা বোঝায়, সম্ভবত কিছুই নয়। ( সাধারণত আপনি যদি কোনও কমান্ড জারি করেন তবে touch foo/bar, foo/barফাইলটি তৈরির আগে প্যাথনামটি অবশ্যই আপনার জন্য উপস্থিত থাকতে হবে এবং সম্ভবত সংখ্যায় ব্যবহৃত হতে পারে ))
বেশ কয়েকটি নিখুঁত পথের নাম থাকতে পারে যা একই ফাইলটিকে (বা সম্ভাব্য ফাইল) বোঝায়, বিশেষত পাথরে প্রতীকী লিঙ্কগুলি (syllinks) এর কারণে, তবে সম্ভবত অন্যান্য কারণে (কোনও ডিভাইস কেবল পঠনযোগ্য হিসাবে দু'বার মাউন্ট করা যেতে পারে)। এই জাতীয় প্রতীকগুলি স্পষ্টতা সমাধান করতে পারে বা নাও করতে পারে।
একটি নন-সিমিলিংক ফাইল বা নামের সাথে প্রতীকী লিঙ্কগুলির একটি শৃঙ্খলে পৌঁছে। এটি কীভাবে হয় তার উপর নির্ভর করে এটি একটি নিখুঁত পাথের নাম দিতে পারে বা নাও পারে। এবং কেউ একে একে পরম পথের নাম হিসাবে সমাধান করতে চাইতে পারে না।
readlink fooবিকল্প ব্যতীত কমান্ডটি কেবল তখনই একটি উত্তর দেয় যখন এর যুক্তিটি fooপ্রতীকী লিঙ্ক এবং সেই উত্তরটি সেই সিমিলিংকের মান। অন্য কোনও লিঙ্ক অনুসরণ করা হয় না। উত্তরটি একটি আপেক্ষিক পথ হতে পারে: যা কিছু ছিল সিমিলিংকের যুক্তির।
তবে, readlinkবিকল্পগুলি (-f -e বা -m) রয়েছে যা সমস্ত ফাইলের জন্য কাজ করবে এবং যুক্তিতে প্রমাণিত ফাইলটিকে একটি পরম পথ (কোনও সিমলিঙ্কযুক্ত নয়) দেবে।
এটি এমন কোনও কিছুর জন্য সূক্ষ্মভাবে কাজ করে যা কোনও সিমলিংক নয়, যদিও কেউ হয়তো মধ্যবর্তী চিহ্নগুলি সমাধান না করেই পরম পথ ব্যবহার করতে আগ্রহী desire এটি কমান্ড দ্বারা সম্পন্ন হয়realpath -s foo
কোনও সিমিলিংকের যুক্তির ক্ষেত্রে, readlinkএর বিকল্পগুলি আবার যুক্তির নিখুঁত পথে সমস্ত সিমলিংকগুলি সমাধান করবে, তবে এটিতে যুক্তিটির মান অনুসরণ করে যে সমস্ত প্রতিলিঙ্কের মুখোমুখি হতে পারে সেগুলিও অন্তর্ভুক্ত থাকবে। আপনি এটি চাইবেন না যে আপনি যদি যুক্তির সাথে সংযুক্ত হতে পারে তার চেয়ে বরং যুক্তি সিএমলিংকের কাছে একটি নিখুঁত পথ চান। আবার, যদি fooএকটি সিমিলিংক হয়, realpath -s fooযুক্তি হিসাবে দেওয়া একটি সহ, সিমলিংকগুলি সমাধান না করেই একটি নিখুঁত পথ পাবে।
ছাড়া -sবিকল্প, realpathহিসাবে একই প্রায় কাছাকাছি আছে
readlinkকেবল একটি লিঙ্ক মান, সেইসাথে বিভিন্ন অন্যান্য বিষয়ের পড়ার জন্য ব্যতীত। readlinkএটির বিকল্পগুলি কেন রয়েছে তা কেবল আমার কাছে পরিষ্কার নয় , এগুলি আপাতভাবে একটি অনাকাঙ্ক্ষিত রিডানডেন্সি তৈরি করে
realpath।
ওয়েবে অন্বেষণ আরও কিছু বলতে পারে না, ব্যতীত সিস্টেমগুলির মধ্যে কিছু ভিন্নতা থাকতে পারে।
উপসংহার: realpathকমপক্ষে এখানে অনুরোধ করা ব্যবহারের জন্য সর্বাধিক নমনীয়তা সহ ব্যবহার করার জন্য সেরা কমান্ড।
আমার প্রিয় সমাধানটি ছিল একটি কারণ এটি অন্যান্য ইউটিলিটি উপস্থিতিতে (coreutils প্যাকেজ) পরোক্ষভাবে করা হয়নি @EugenKonkov দ্বারা।
তবে এটি আপেক্ষিক পথে ব্যর্থ হয়েছে ""। এবং "..", সুতরাং এখানে এই বিশেষ ক্ষেত্রে পরিচালনা করার জন্য কিছুটা উন্নত সংস্করণ দেওয়া আছে।
যদিও ব্যবহারকারীর cdআপেক্ষিক পথের পিতৃ ডিরেক্টরিতে প্রবেশের অনুমতি না থাকলে এটি এখনও ব্যর্থ হয় ।
#! /bin/sh
# Takes a path argument and returns it as an absolute path.
# No-op if the path is already absolute.
function to-abs-path {
local target="$1"
if [ "$target" == "." ]; then
echo "$(pwd)"
elif [ "$target" == ".." ]; then
echo "$(dirname "$(pwd)")"
else
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
fi
}
ইউজেনের উত্তর আমার পক্ষে বেশ কার্যকর হয়নি তবে এটি হয়েছে:
absolute="$(cd $(dirname \"$file\"); pwd)/$(basename \"$file\")"
পার্শ্ব নোট, আপনার বর্তমান কাজ ডিরেক্টরিটি প্রভাবিত নয়।
সবচেয়ে ভাল সমাধান, ইমো, এখানে পোস্ট করা একটি: https://stackoverflow.com/a/3373298/9724628 ।
এটি অজগর কাজ করতে প্রয়োজন, কিন্তু এটি সমস্ত বা বেশিরভাগ প্রান্তের কেসগুলি আবৃত করে এবং খুব বহনযোগ্য সমাধান হতে পারে বলে মনে হয়।
python -c "import os,sys; print(os.path.realpath(sys.argv[1]))" path/to/file
python -c "import os,sys; print(os.path.abspath(sys.argv[1]))" path/to/file
আপনি যদি ম্যাক ওএস এক্সে ব্যাশ ব্যবহার করছেন যা রিয়েলপথের অস্তিত্বই নেই বা এর পাঠ্য লিঙ্কটি চূড়ান্ত পথে মুদ্রণ করতে পারে না, তবে এটি মুদ্রণের জন্য আপনার নিজের সংস্করণ কোড করার বিকল্প থাকতে পারে। আমার বাস্তবায়ন এখানে:
(খাঁটি বাশ)
abspath(){
local thePath
if [[ ! "$1" =~ ^/ ]];then
thePath="$PWD/$1"
else
thePath="$1"
fi
echo "$thePath"|(
IFS=/
read -a parr
declare -a outp
for i in "${parr[@]}";do
case "$i" in
''|.) continue ;;
..)
len=${#outp[@]}
if ((len==0));then
continue
else
unset outp[$((len-1))]
fi
;;
*)
len=${#outp[@]}
outp[$len]="$i"
;;
esac
done
echo /"${outp[*]}"
)
}
(গাওক ব্যবহার করুন)
abspath_gawk() {
if [[ -n "$1" ]];then
echo $1|gawk '{
if(substr($0,1,1) != "/"){
path = ENVIRON["PWD"]"/"$0
} else path = $0
split(path, a, "/")
n = asorti(a, b,"@ind_num_asc")
for(i in a){
if(a[i]=="" || a[i]=="."){
delete a[i]
}
}
n = asorti(a, b, "@ind_num_asc")
m = 0
while(m!=n){
m = n
for(i=1;i<=n;i++){
if(a[b[i]]==".."){
if(b[i-1] in a){
delete a[b[i-1]]
delete a[b[i]]
n = asorti(a, b, "@ind_num_asc")
break
} else exit 1
}
}
}
n = asorti(a, b, "@ind_num_asc")
if(n==0){
printf "/"
} else {
for(i=1;i<=n;i++){
printf "/"a[b[i]]
}
}
}'
fi
}
(খাঁটি বিএসডি অ্যাডক)
#!/usr/bin/env awk -f
function abspath(path, i,j,n,a,b,back,out){
if(substr(path,1,1) != "/"){
path = ENVIRON["PWD"]"/"path
}
split(path, a, "/")
n = length(a)
for(i=1;i<=n;i++){
if(a[i]==""||a[i]=="."){
continue
}
a[++j]=a[i]
}
for(i=j+1;i<=n;i++){
delete a[i]
}
j=0
for(i=length(a);i>=1;i--){
if(back==0){
if(a[i]==".."){
back++
continue
} else {
b[++j]=a[i]
}
} else {
if(a[i]==".."){
back++
continue
} else {
back--
continue
}
}
}
if(length(b)==0){
return "/"
} else {
for(i=length(b);i>=1;i--){
out=out"/"b[i]
}
return out
}
}
BEGIN{
if(ARGC>1){
for(k=1;k<ARGC;k++){
print abspath(ARGV[k])
}
exit
}
}
{
print abspath($0)
}
উদাহরণ:
$ abspath I/am/.//..//the/./god/../of///.././war
/Users/leon/I/the/war
যদি আপেক্ষিক পথটি ডিরেক্টরি পথ হয় তবে আমার চেষ্টা করুন, সেরা হওয়া উচিত:
absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)
echo $absPath
echo "mydir/doc/ mydir/usoe ./mydir/usm" | awk '{ split($0,array," "); for(i in array){ system("cd "array[i]" && echo $PWD") } }'
@ আর্নেস্ট-এর পরিবর্তে সুন্দর সংস্করণে উন্নতি:
absolute_path() {
cd "$(dirname "$1")"
case $(basename $1) in
..) echo "$(dirname $(pwd))";;
.) echo "$(pwd)";;
*) echo "$(pwd)/$(basename $1)";;
esac
}
সঠিকভাবে ক্ষেত্রে যেখানে পথের শেষ উপাদান সঙ্গে এই চুক্তি .., যে ক্ষেত্রে "$(pwd)/$(basename "$1")"মধ্যে @ আর্নেস্ট-একটি এর উত্তর হিসাবে মাধ্যমে আসবে accurate_sub_path/spurious_subdirectory/..।
আপনি যদি কোনও আপেক্ষিক পাথযুক্ত একটি ভেরিয়েবলকে পরম পথে রূপান্তর করতে চান তবে এটি কাজ করে:
dir=`cd "$dir"`
"সিডি" ওয়ার্কিং ডিরেক্টরি পরিবর্তন না করে প্রতিধ্বনিত হয়, কারণ এখানে একটি সাব-শেলতে কার্যকর করা হয়েছে।
dir=`cd ".."` && echo $dir
এটি অন্য সকলের একটি শৃঙ্খলিত সমাধান, উদাহরণস্বরূপ, যখন realpathব্যর্থ হয়, হয় এটি ইনস্টল না হওয়ার কারণে বা এটি ত্রুটি কোড সহ প্রস্থান করে, তারপরে, সঠিক সমাধান না পাওয়া পর্যন্ত পরবর্তী সমাধানটি চেষ্টা করা হয়।
#!/bin/bash
function getabsolutepath() {
local target;
local changedir;
local basedir;
local firstattempt;
target="${1}";
if [ "$target" == "." ];
then
printf "%s" "$(pwd)";
elif [ "$target" == ".." ];
then
printf "%s" "$(dirname "$(pwd)")";
else
changedir="$(dirname "${target}")" && basedir="$(basename "${target}")" && firstattempt="$(cd "${changedir}" && pwd)" && printf "%s/%s" "${firstattempt}" "${basedir}" && return 0;
firstattempt="$(readlink -f "${target}")" && printf "%s" "${firstattempt}" && return 0;
firstattempt="$(realpath "${target}")" && printf "%s" "${firstattempt}" && return 0;
# If everything fails... TRHOW PYTHON ON IT!!!
local fullpath;
local pythoninterpreter;
local pythonexecutables;
local pythonlocations;
pythoninterpreter="python";
declare -a pythonlocations=("/usr/bin" "/bin");
declare -a pythonexecutables=("python" "python2" "python3");
for path in "${pythonlocations[@]}";
do
for executable in "${pythonexecutables[@]}";
do
fullpath="${path}/${executable}";
if [[ -f "${fullpath}" ]];
then
# printf "Found ${fullpath}\\n";
pythoninterpreter="${fullpath}";
break;
fi;
done;
if [[ "${pythoninterpreter}" != "python" ]];
then
# printf "Breaking... ${pythoninterpreter}\\n"
break;
fi;
done;
firstattempt="$(${pythoninterpreter} -c "import os, sys; print( os.path.abspath( sys.argv[1] ) );" "${target}")" && printf "%s" "${firstattempt}" && return 0;
# printf "Error: Could not determine the absolute path!\\n";
return 1;
fi
}
printf "\\nResults:\\n%s\\nExit: %s\\n" "$(getabsolutepath "./asdfasdf/ asdfasdf")" "${?}"
আপনি যে কোনও আপেক্ষিক পাথ $ লাইনের জন্য ব্যাশ স্ট্রিং বিকল্প ব্যবহার করতে পারেন:
line=$(echo ${line/#..\//`cd ..; pwd`\/})
line=$(echo ${line/#.\//`pwd`\/})
echo $line
মৌলিক ফ্রন্ট-অফ-স্ট্রিং প্রতিস্থাপনটি সূত্রটি অনুসরণ করে
{{স্ট্রিং / # স্ট্রিং / রিপ্লেসমেন্ট}
যা এখানে ভাল আলোচনা করা হয়েছে: https://www.tldp.org/LDP/abs/html/string-manipulation.html
\চরিত্র negates /যখন আমরা এটা স্ট্রিংটি আমরা খুঁজে / প্রতিস্থাপন অংশ হতে চাই।
আমি ম্যাক ওএস ক্যাটালিনা, উবুন্টু 16 এবং সেন্টোস 7 এর মধ্যে খুব সুন্দরভাবে বহনযোগ্য কোনও সমাধান খুঁজে পাচ্ছিলাম না, তাই আমি পাইথন ইনলাইন দিয়ে এটি করার সিদ্ধান্ত নিয়েছিলাম এবং এটি আমার ব্যাশ স্ক্রিপ্টগুলির জন্য ভাল কাজ করেছে।
to_abs_path() {
python -c "import os; print os.path.abspath('$1')"
}
to_abs_path "/some_path/../secrets"