ওএস এক্স থেকে একটি স্বেচ্ছাসেবী ফাইলের পরম পথটি কীভাবে পুনরুদ্ধার করবেন


18

আমি একটি সাধারণ কমান্ডের সন্ধান করছি যা কোনও ওএস এক্স-এর (লিনাক্সের অধীনে `` রিডলিংক-ফ''র অনুরূপ) ফাইলের পরম এবং ক্যানোনিকালাইজড পাথের জন্য বাশের মধ্যে ব্যবহার করা যেতে পারে।

নিম্নলিখিত নমুনা বাশ সেশনটি [`অবস্পথ'` নামে একটি [কল্পিত] ইউটিলিটি বর্ণনা করে যা পছন্দসই আচরণ প্রদর্শন করে:

$ pwd
/Users/guyfleegman

$ ls -lR
drwxr-xr-x  4 guyfleegman  crew  136 Oct 30 02:09 foo

./foo:
-rw-r--r--  1 guyfleegman  crew  0 Oct 30 02:07 bar.txt
lrwxr-xr-x  1 guyfleegman  crew  7 Oct 30 02:09 baz.txt -> bar.txt


$ abspath .
/Users/guyfleegman

$ abspath foo
/Users/guyfleegman/foo

$ abspath ./foo/bar.txt
/Users/guyfleegman/foo/bar.txt

$ abspath foo/baz.txt
/Users/guyfleegman/foo/baz.txt

উপরের উদাহরণে `` abspath'` এর সর্বশেষ আহবান হিসাবে, আমি পছন্দ করি এটি স্বয়ংক্রিয়ভাবে সিমলিংকগুলি সমাধান না করে, তবে আমি এখানে খুব পিক হতে চাই না।


উত্তর:


16
function abspath() { pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname \"$1\"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename \"$1\"`"; else echo "$cur_dir/`basename \"$1\"`"; fi; fi; popd > /dev/null; }

উদাহরণ:

abspath / => /

abspath /.DS_Store => /.DS_Store

abspath ~ => /Users/mschrag

cd /tmp; abspath . => /tmp

cd /; abspath .DS_Store => /.DS_Store

11

আমি মনে করি না একটি বিল্টিন কমান্ড আছে যা এটি করে। জেসি উইলসন এটির জন্য একটি বাশ স্ক্রিপ্ট লিখেছিলেন:

#!/bin/bash
cd -P -- "$(dirname -- "$1")" &&
printf '%s\n' "$(pwd -P)/$(basename -- "$1")"

যাইহোক, এটা সরাসরি নিচের পাথ জন্য ভাল কাজ করে না /, যেমন /etc(প্রিন্টিং //etc), সেইসাথে .এবং ..(মুদ্রণ /cwd/.উভয় ক্ষেত্রেই)। আমি এটিকে সংশোধন করার চেষ্টা করেছি, তবে আমার অপর্যাপ্ত বাশ-ফু আমাকে ব্যর্থ করেছিল।

আমার পরামর্শটি এখানে:

#!/usr/bin/env python
import os.path
import sys

for arg in sys.argv[1:]:
    print os.path.abspath(arg)

এর মতো /usr/bin/abspathবা এর মতো কিছু সংরক্ষণ করুন এবং এটিকে সম্পাদনযোগ্য করে তুলুন। নমুনা আউটপুট:

Servus08:~ danielbeck$ abspath .
/Users/danielbeck
Servus08:~ danielbeck$ abspath /tmp
/tmp
Servus08:~ danielbeck$ abspath Documents
/Users/danielbeck/Documents
Servus08:~ danielbeck$ abspath . /tmp Documents
/Users/danielbeck
/tmp
/Users/danielbeck/Documents

আপনি যদি না সিমবলিক লিঙ্ক রেজল্যুশন চাই, পরিবর্তন printভালো লাইন:

    print os.path.realpath(os.path.abspath(arg))

এটি পেতে:

Servus08:~ danielbeck$ abspath . /tmp Documents
/Users/danielbeck
/private/tmp
/Users/danielbeck/Documents

1
আমি মনে করি আপনি প্রথম শেল-ভিত্তিক পদ্ধতির সাথে সঠিক পথে রয়েছেন তবে আমি বিশ্বাস করি যে এটি করার জন্য অন্য একটি ভাষা ব্যবহার করা উদ্দেশ্যকে কিছুটা হ্রাস করে, কারণ এটি অতিরিক্ত নির্ভরতা প্রবর্তন করে এবং জিএনইউ'র সংস্করণটি কেবল `রিডলিংকের সংকলনের সমতুল্য equivalent (1) 'ওএস এক্স এর অধীনে (ধরে নেওয়া যায় যে এটি করা যেতে পারে; আমি এটি এখনও যাচাই করি নি)।
মাইকেল ওয়েহনার

2
@ মিশেল আপনি জিএনইউ রিডলিংক সহ কোনও সিস্টেমে আছেন, না ওএস এক্সে - ঠিক? ওএস এক্সের পাইথনটি বাক্সের বাইরে রয়েছে। তত্ত্বগতভাবে এটি একটি নতুন নির্ভরতা, বাস্তবে নয়। যাইহোক, আমি আপনাকে যা অফার করতে পারি তা সবই।
ড্যানিয়েল বেক

আপনি যে বাস্তববাদী পদ্ধতিটি বোঝাচ্ছেন তা প্রশংসনীয়, যদি অতিরিক্ত মাত্রায় সরল থাকে। যাই হোক না কেন, যদি আমরা ব্যাশে লিখিতভাবে নিখুঁতভাবে লিখিত কিছু (যা একেবারেই করণীয় এবং অন্য কোনও কিছুর উপর নির্ভর করে না - এটি কেবল একটি লাইনে সহজেই করা যায় না) এর পরিবর্তে এই দৃষ্টিভঙ্গিটি গ্রহণ করি, পাইথন সম্ভবত আইসন নয় সেরা পছন্দ না। পার্ল এবং রুবি উভয়ই (এবং সম্ভবত পিএইচপি) প্রকৃত স্ক্রিপ্ট ফাইল তৈরির প্রয়োজন ছাড়াই কমান্ড লাইনে এটি সংক্ষেপে করতে পারে।
মাইকেল ওয়েহনার

1
@ মিশেল: সত্য, তবে আমি এ সম্পর্কে মন্তব্য করছি না। আমি আপনাকে জেসি উইলসনের বিশুদ্ধ ব্যাশে লিখিত 90% সমাধানের প্রস্তাব দিচ্ছি + বিশ্লেষণ কেন এটি কেবল 90%। যদি আপনার কোনও সমস্যা না হয় তবে তা ঠিক আছে। পাইথনে আমি আপনাকে আরও জটিল, 100% সমাধান দিয়েছি। অন্যান্য স্ক্রিপ্টিং ল্যাঙ্গুয়েজগুলি ব্রেফার হতে পারে (পার্ল কুখ্যাতভাবে সুতরাং :-)), কমান্ডটি সংরক্ষণ করার জন্য সকলের জন্য একটি অতিরিক্ত ফাইলের প্রয়োজন। বা আপনি এটি ব্যবহার করতে চাইলে প্রতিবারই এটি লিখতে চান? এজন্যই আমি একাধিক পরামিতি হ্যান্ডল করার জন্য মাল্টি-লাইন ক্ষমতা যুক্ত করেছি, 1 বা 2 লাইন তারপরে আলাদা করবেন না।
ড্যানিয়েল বেক

2
@ মিশেল, পাইথন ওএস এক্সে কেন ভাল পছন্দ হবে না? এমনকি কমান্ডগুলি সহ জাহাজগুলি যা আসলে পাইথন স্ক্রিপ্টগুলি যেমনfile /usr/bin/xattr
আরজান

8

একটি বিকল্প কেবল কোর্টিল ইনস্টল করা এবং ব্যবহার করা হবে greadlink -f। এটি সিমলিংকগুলি সমাধান করে এবং এটি বিদ্যমান /Foo/বা ~/foo.txtনা থাকলে এটির সাথে কাজ করে তবে অস্তিত্ব /Foo/foo.txtথাকলে /Foo/তা নয়।

$ brew install coreutils
$ greadlink -f /etc
/private/etc
$ greadlink -f ~/Documents/
/Users/lauri/Documents
$ greadlink -f ..
/Users
$ greadlink -f //etc/..////
/private
$ greadlink -f /Foo
/Foo
$ greadlink -f /Foo/foo.txt
$ 

এটি প্রতিলিঙ্কগুলি সমাধান করে না এবং এটির সাথেও কাজ করে না /Foo/foo.txt

abspath() {
  if [ -d "$1" ]; then
    ( cd "$1"; dirs -l +0 )
  else
    ( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
  fi
}

abspath /etc # /etc
abspath ~/Foo/foo.txt # doesn't work
abspath ~/Foo # works
abspath .
abspath ./
abspath ../
abspath ..
abspath /
abspath ~
abspath ~/
abspath ~/Documents
abspath /\"\ \'
abspath /etc/../etc/
abspath /private//etc/
abspath /private//
abspath //private # //private
abspath ./aa.txt
abspath aa.tar.gz
abspath .aa.txt
abspath /.DS_Store
abspath ~/Documents/Books/

dirs -lটিলডে সম্প্রসারণ সম্পাদন করে। dirs +0স্ট্যাকের অন্যান্য ডিরেক্টরি থাকলে কেবল শীর্ষস্থানীয় ডিরেক্টরি মুদ্রণ করে।


2

আমার ধারণা আপনি পাইথন বা রুবি দিয়ে এটি করতে পারেন।

$ ruby -e 'puts File.expand_path("~/somepath")'

অথবা এটি দিয়ে একটি কমান্ড তৈরি করুন

#!/usr/bin/env ruby
puts File.expand_path(ARGV[0])

ড্যানিয়েল বেকের উত্তর সম্পর্কে আমার পূর্ববর্তী মন্তব্যটি এখানেও প্রযোজ্য (আমি একটি নিখুঁতভাবে বাশ-ওয়াই সমাধানটিই পছন্দ করতাম), যদিও আমি যদি অন্য ভাষাগুলি ব্যবহার করে এটি অর্জন করতে চাই তবে আমি এর সমাধানের জন্য আপনার সমাধানটি এখন পর্যন্ত সবচেয়ে ভাল পছন্দ করি। :) আমি সম্ভবত রুবিতে কলটি আবদ্ধ করতাম (উদাহরণস্বরূপ ফাংশন অ্যাবস্পাথ () y রুবি -e "ফাইল.এক্সপ্যান্ড_পাথ ('$ 1')";}) রাখে এবং আমার pr। প্রোফাইলে 'রেখে দিয়েছি।
মাইকেল ওয়েহনার

1

আপনার যদি পার্লের জন্য ফাইল :: স্পেস মডিউল ইনস্টল করা থাকে তবে আপনি কেবল এটি করতে পারেন:

perl -MFile::Spec -e 'print File::Spec->rel2abs("../however/complex/../you/want/to.get"), "\n"'

0

বাশ / শ স্ক্রিপ্টগুলির জন্য আপনি এই পুনরাবৃত্ত ফাংশনটি ব্যবহার করতে পারেন:

canonical_readlink ()
{
    cd `dirname $1`;
    __filename=`basename $1`;
    if [ -h "$__filename" ]; then
        canonical_readlink `readlink $__filename`;
    else
        echo "`pwd -P`";
    fi
}

answer=$(canonical_readlink $0)

কিছু ভেরিয়েবল এবং কমান্ড বিকল্পগুলি সঠিকভাবে উদ্ধৃত হয় না। আপনি ভেরিয়েবল নামের পরিবর্তে স্থানীয় ভেরিয়েবল ব্যবহার করতে পারেন __filename। স্ক্রিপ্ট বর্তমানে dirnameযাইহোক আরও বেশি আচরণ করে ।
ল্রি

0

ওএসএক্সের জন্য নিম্নলিখিত গ্রন্থাগারটি ইনস্টল করুন:

brew install coreutils

greadlink -f file.txt

0

যদি কোর্টিলগুলি ইনস্টল করা কোনও বিকল্প না হয়, নিম্নলিখিত সিমলিংকের কম্বোগুলি পরিচালনা করে। এবং .. এবং জিএনইউ রিয়েলপথের মতো ফাইল এবং ফোল্ডারে কাজ করে:

#!/usr/bin/env bash
realpath()
{
    if ! pushd $1 &> /dev/null; then 
        pushd ${1##*/} &> /dev/null
        echo $( pwd -P )/${1%/*}
    else
        pwd -P
    fi
    popd > /dev/null
}

তবে এটি রিয়েলপ্যাটের - সম্পর্কিত সম্পর্কিতটিকে সমর্থন করে না। এর জন্য /programming//a/12498485/869951 প্রয়োজন হবে ।


0

এই সীমাবদ্ধতাটি ম্যাকোস (সেই সময়ে ওএস এক্স), পিএইচপি ডিফল্টরূপে উপলব্ধ। এটি ফাইলের মূল ডিরেক্টরিটি ফিরিয়ে দেবে। dirnameফাইলটি পেতেও সরান ।

export SOURCE_DIRECTORY="$(php -r 'echo dirname(realpath($argv[1]));' -- "${BASH_SOURCE[0]}")"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.