bash / fish कमांड को फाइल में निरपेक्ष पथ प्रिंट करने के लिए


448

प्रश्न: वहाँ एक साधारण श / बाश / zsh / मछली / है ... जो भी मैं इसे खिला फ़ाइल का पूर्ण पथ मुद्रित करने के लिए आदेश?

प्रयोग मामला: मैं निर्देशिका में कर रहा हूँ /a/bऔर मैं फाइल करने के लिए पूरा पथ प्रिंट करना चाहते हैं cताकि मैं आसानी से एक अन्य कार्यक्रम में पेस्ट कर सकते कमांड लाइन पर: /a/b/c। सरल, अभी तक यह करने के लिए एक छोटा सा कार्यक्रम शायद मुझे 5 या इतने सेकंड बचा सकता है जब यह लंबे रास्तों को संभालने के लिए आता है, जो अंत में जोड़ता है। तो यह मुझे आश्चर्य है कि मैं ऐसा करने के लिए एक मानक उपयोगिता नहीं पा सकता हूं - क्या वास्तव में कोई नहीं है?

यहाँ एक नमूना कार्यान्वयन, abspath.py:

#!/usr/bin/python
# Author: Diggory Hardy <diggory.hardy@gmail.com>
# Licence: public domain
# Purpose: print the absolute path of all input paths

import sys
import os.path
if len(sys.argv)>1:
    for i in range(1,len(sys.argv)):
        print os.path.abspath( sys.argv[i] )
    sys.exit(0)
else:
    print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
    sys.exit(1)

मेरा तर्क है कि @ DennisWilliamson का जवाब (-m विकल्प का उपयोग करना) बेहतर है (आमतौर पर) अधिक पोर्टेबल होने और फाइलों के साथ काम करने के लिए जो मौजूद नहीं हैं।
टीटीटी

या फ्लिम का जवाब; दोनों अच्छे समाधान हैं। हालांकि बैनियर ने मेरे मूल प्रश्न का सबसे अच्छा जवाब दिया ।
12

3
OSX उपयोगकर्ता: इस उत्तर को
Ian

जवाबों:


562

कोशिश करो realpath

$ realpath example.txt
/home/username/example.txt

133
+1, बहुत अच्छा कार्यक्रम। लेकिन ध्यान दें कि यह एक बाहरी कमांड है (शेल निर्मित नहीं है) और डिफ़ॉल्ट रूप से हर सिस्टम में मौजूद नहीं हो सकता है, अर्थात आपको इसे स्थापित करने की आवश्यकता हो सकती है। डेबियन में यह एक ही नाम के साथ एक अलग पैकेज में रहता है।
रोमन चेप्लाकाका

5
मैंने अपने पथ को इसमें realpathशामिल किया: github.com/westonruter/misc-cli-tools/blob/master/realpath
वेस्टन रटर

1
@ फ़ीलम: यह अभी भी आपको कुछ रिश्तेदार मार्ग दिए गए वैध मार्ग देगा। यदि आप फ़ाइल के अस्तित्व के बारे में जानना चाहते हैं, तो उदाहरण के लिए किसी अन्य उपकरण का उपयोग करें जैसे कि परीक्षण।
बेंजामिन बैनिएर

14
@ डालिन: कोरुटिल स्थापित करने का प्रयास करें। बाइनरी का नाम grealpath है।
टोनी पेन्या-अल्बा

5
यह उपकरण GNU कोरुटिल्स 8.15 (2012 में) में पेश किया गया था, इसलिए यह काफी नया है।
marbu

319

कोशिश करें readlinkजो प्रतीकात्मक लिंक को हल करेगा:

readlink -e /foo/bar/baz

50
मैं '-ई' के बजाय '-फ' का उपयोग करूंगा ताकि हम एक बिना फाइल के निरपेक्ष पथ देख सकें।
hluk

5
यह पोर्टेबल होने के साथ-साथ मुझे सबसे सरल लगता है। रीडलिंक ग्नू कोरुटिल्स का बंदरगाह है, इसलिए इसे कुछ एम्बेडेड वितरणों को छोड़कर लगभग किसी भी लिनक्स वितरण पर स्थापित किया जाएगा।
कैटफ़ाइव

14
यह मुझे लगता है कि -mउपयोग करने के लिए सबसे अच्छा विकल्प है।
मैट जॉइनर

1
@ डालिन: /usr/bin/readlinkमावेरिक्स पर। या क्या आपका मतलब है कि ओएस एक्स पर वे विकल्प नहीं पाए जाते हैं? यह एक मंचित बीएसडी संस्करण लगता है ...: पी
इकोनॉस्टल

14
@iconoclast ओएसएक्स पर वे विकल्प उपलब्ध नहीं हैं, और बीएसडी readlinkमैनपेज के अनुसार : only the target of the symbolic link is printed. If the given argument is not a symbolic link, readlink will print nothing and exit with an errorइसलिए, रीडिंक OSX पर इस उद्देश्य के लिए काम नहीं करेगा
SnoringFrog

257
#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"

8
सभी सामान उद्धृत करने के लिए मत भूलना। यदि आपको समझ में नहीं आता है, तो अपने प्रोग्राम को एक फ़ाइल पर आज़माएँ a b(a और b के बीच दो रिक्त स्थान, SO उनमें से एक खाता है)।
रोमन चेप्लाकाका

1
इस पर भी प्रयास करें "/" यह "///" में बदल जाता है
जॉर्ज

35
अब तक का एकमात्र POSIX समाधान जिसे आपको पढ़ने और लिखने के लिए एक निष्पादन योग्य संकलन करने की आवश्यकता नहीं है, क्योंकि readlink और realpath POSIX नहीं हैं
Ciro Santilli 郝海东 solution solution solution '

25
मैं ओएस एक्स पर function realpath { echo $(cd $(dirname $1); pwd)/$(basename $1); }खुद को एक realpathकमांड (वर्तमान में स्वीकृत उत्तर) बनाता था। धन्यवाद!
जेम्स बेडफोर्ड

1
मैंने स्क्रिप्ट के लिए लॉग फाइलनेम को परिभाषित करने के लिए इस विधि का उपयोग किया:LOG=$(echo $(cd $(dirname $0); pwd)/$(basename $0 .sh).log)
DrStrangepork

85

के बारे में भूल जाओ readlinkऔर realpathजो आपके सिस्टम पर स्थापित हो भी सकता है और नहीं भी।

यहां ऊपर डॉगबैन के उत्तर पर विस्तार से इसे एक समारोह के रूप में व्यक्त किया गया है:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}

आप इसे इस तरह उपयोग कर सकते हैं:

myabsfile=$(get_abs_filename "../../foo/bar/file.txt")

यह कैसे और क्यों काम करता है?

समाधान इस तथ्य का शोषण करता है कि बैश बिल्ट-इन pwdकमांड वर्तमान निर्देशिका के निरपेक्ष पथ को बिना तर्क के लागू किया जाएगा।

मुझे यह समाधान क्यों पसंद है?

यह पोर्टेबल है और न ही आवश्यकता नहीं है readlinkया realpathजो अक्सर एक डिफ़ॉल्ट पर मौजूद नहीं है किसी दिए गए लिनक्स / यूनिक्स distro के स्थापित करें।

क्या होगा अगर डायर मौजूद नहीं है?

जैसा कि फ़ंक्शन के ऊपर दिया गया है, विफल हो जाएगा और यदि निर्देशिका पथ मौजूद नहीं है तो stderr पर प्रिंट करें। यह वह नहीं हो सकता जो आप चाहते हैं। आप उस स्थिति को संभालने के लिए फ़ंक्शन का विस्तार कर सकते हैं:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  if [ -d "$(dirname "$1")" ]; then
    echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
  fi
}

अब यह एक खाली स्ट्रिंग लौटाएगा यदि एक मूल डायर मौजूद नहीं है।

आप '..' या 'अनुगामी कैसे संभालते हैं?' इनपुट में

ठीक है, यह उस मामले में एक पूर्ण मार्ग देता है, लेकिन न्यूनतम नहीं। ऐसा लगेगा:

/Users/bob/Documents/..

यदि आप '..' को हल करना चाहते हैं, तो आपको स्क्रिप्ट बनाने की आवश्यकता होगी:

get_abs_filename() {
  # $1 : relative filename
  filename=$1
  parentdir=$(dirname "${filename}")

  if [ -d "${filename}" ]; then
      echo "$(cd "${filename}" && pwd)"
  elif [ -d "${parentdir}" ]; then
    echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
  fi
}

अच्छा काम है, लेकिन जाहिर है आप सवाल समझ में नहीं आया। मैं इंटरैक्टिव उपयोग के लिए कुछ चाहता था, स्क्रिप्ट नहीं।
१dy

3
मैं यह जोड़ना चाहूंगा कि realpathकोरुटिल्स पैकेज से आता है, जिसमें उपकरण भी होते हैं जैसे कि who, touchया cat। यह GNU टूल्स का काफी स्टैण्डर्ड सेट है, इसलिए आप यह सुनिश्चित कर सकते हैं कि यह लगभग किसी भी linux आधारित मशीन पर स्थापित है। क्या कहा, आप सही हैं: इसके साथ 2 समस्याएँ हैं: i) आप इसे डिफ़ॉल्ट रूप से इंस्टॉल करने से चूक जाएंगे गैर GNU यूनिक्स सिस्टम (जैसे OpenBSD) ii) इस उपकरण को 8.15 संस्करण में पेश किया गया था (इसलिए यह 2012 से काफी नया है), इसलिए आप इसे दीर्घकालिक स्थिर प्रणालियों (जैसे RHEL 6) पर याद करेंगे।
मार्बु

1
खैर, यह कम से कम लगता है कि कॉन्टिनम एनालिटिक्स ( एनाकोंडा पायथन वितरण के निर्माताओं ) को यह जवाब पसंद आया। यह उनके "सक्रिय" स्क्रिप्ट में एक संदर्भ के साथ (यहां वापस जोड़ने के साथ) लागू किया गया है, जो कि कॉन्डा टूल द्वारा बनाए गए आभासी वातावरण को सक्रिय करने के लिए उपयोग किया जाता है। तो ... अच्छा!
wjv

1
यह केवल निर्देशिका के लिए काम करता है (क्योंकि कोई और नहीं है) और ".." और "" के साथ सामना नहीं कर सकता। मेरा जवाब देखें कि सब कुछ संभालना चाहिए: stackoverflow.com/a/23002317/2709
अलेक्जेंडर क्लिमेत्स्क

3
@marbu realpath उबंटू 14.04, या डेबियन व्हीज़ी पर मौजूद नहीं है। यह समय के साथ कुछ मानक बन सकता है, लेकिन यह निश्चित रूप से अब नहीं है। यह भी ध्यान दें कि ओपी ने लिनक्स या जीएनयू के बारे में कुछ नहीं कहा। उससे अधिक व्यापक रूप से बैश का उपयोग किया जाता है।
mc0e

77
$ readlink -m FILE
/path/to/FILE

यह readlink -e FILEया से बेहतर है realpath, क्योंकि यह तब भी काम करता है जब फ़ाइल मौजूद नहीं है।


अच्छा लगा। यह उन फ़ाइलों / निर्देशिकाओं पर भी काम करता है जो अस्तित्व में हैं, लेकिन सहानुभूति नहीं हैं।
शांत मन

मेरे पास ओएस एक्स 10.9 (मावेरिक्स) पर रीडलिंक उपलब्ध है, इसलिए यह निश्चित रूप से यहां सबसे अच्छा जवाब है।
केनेथ होस्ट 20

6
@KennethHoste: -mविकल्प Mavericks पर उपलब्ध नहीं है।
आइकनोकॉस्ट

2
निश्चित रूप से यह DEFAULT OSX इंस्टॉलेशन पर नहीं है।
फ्रेंक मरोजा

linux पर काम करता है (CentOS) धन्यवाद, क्योंकि realpath इसके लिए मौजूद नहीं था
jimh

66

निरपेक्ष पथ कनवर्टर शेल फ़ंक्शन के लिए यह सापेक्ष पथ

  • कोई उपयोगिताओं (बस cdऔर pwd) की आवश्यकता है
  • निर्देशिका और फ़ाइलों के लिए काम करता है
  • संभालता है ..और.
  • dir या filenames में रिक्त स्थान को संभालता है
  • फ़ाइल या निर्देशिका की आवश्यकता है
  • दिए गए रास्ते पर कुछ नहीं होने पर कुछ भी नहीं मिलता है
  • इनपुट के रूप में निरपेक्ष पथ को संभालता है (आवश्यक रूप से उन्हें गुजरता है)

कोड:

function abspath() {
    # generate absolute path from relative path
    # $1     : relative filename
    # return : absolute path
    if [ -d "$1" ]; then
        # dir
        (cd "$1"; pwd)
    elif [ -f "$1" ]; then
        # file
        if [[ $1 = /* ]]; then
            echo "$1"
        elif [[ $1 == */* ]]; then
            echo "$(cd "${1%/*}"; pwd)/${1##*/}"
        else
            echo "$(pwd)/$1"
        fi
    fi
}

नमूना:

# assume inside /parent/cur
abspath file.txt        => /parent/cur/file.txt
abspath .               => /parent/cur
abspath ..              => /parent
abspath ../dir/file.txt => /parent/dir/file.txt
abspath ../dir/../dir   => /parent/dir          # anything cd can handle
abspath doesnotexist    =>                      # empty result if file/dir does not exist
abspath /file.txt       => /file.txt            # handle absolute path input

नोट: यह nolan6000 और bsingh के उत्तरों पर आधारित है , लेकिन फ़ाइल केस को ठीक करता है।

मैं यह भी समझता हूं कि मूल प्रश्न मौजूदा कमांड लाइन उपयोगिता के बारे में था। लेकिन चूँकि इसके लिए स्टैकओवरफ़्लो पर प्रश्न प्रतीत होता है, जिसमें शेल स्क्रिप्ट भी शामिल हैं, जो न्यूनतम निर्भरता चाहते हैं, मैंने इस स्क्रिप्ट का समाधान यहाँ रखा है, इसलिए मैं इसे बाद में खोज सकता हूँ :)


धन्यवाद। यही मैं ओएसएक्स पर जाता हूं
ग्रेग

यह रिक्त स्थान के साथ निर्देशिकाओं के लिए काम नहीं करता है, अर्थात: $ abspath 'a b c/file.txt'ऐसा इसलिए है क्योंकि तर्क को cdउद्धृत नहीं किया गया है। इसे दूर करने के लिए, पूरे तर्क को उद्धृत करने के बजाय echo(क्या इन उद्धरणों का एक कारण है?) केवल पथ तर्क को उद्धृत करें। Ie के echo "$(cd ${1%/*}; pwd)/${1##*/}"साथ बदलें echo $(cd "${1%/*}"; pwd)/${1##*/}
जॉर्ज

@george नोटिंग के लिए धन्यवाद, मैंने इसे ठीक किया।
अलेक्जेंडर क्लिमेत्स्क

1
मैंने आधा-आधा दर्जन समाधानों के माध्यम से देखा और यह निश्चित रूप से सबसे संक्षिप्त और सटीक बैश-एकमात्र समाधान प्रतीत होता है। के echo "$(cd "$1"; pwd)"साथ बदलकर आप इसे और भी पतला कर सकते हैं (cd "$1"; pwd)। यहां गूंज की कोई जरूरत नहीं है।
छह

@ सिक्स ट्रू, अपडेट किया गया। ब्रेसिज़ ( ... )की अभी भी ज़रूरत है, इसलिए cdएक उप-प्रकार में होता है, क्योंकि हम किसी भी कॉलर के लिए कार्यशील निर्देशिका को बदलना नहीं चाहते हैं abspath
अलेक्जेंडर क्लिमेत्स्क

24

findआदेश में मदद मिल सकती

find $PWD -name ex*
find $PWD -name example.log

पैटर्न से मेल खाने वाले नामों के साथ वर्तमान निर्देशिका में या उससे नीचे की सभी फाइलों को सूचीबद्ध करता है। आप इसे सरल कर सकते हैं यदि आप केवल कुछ परिणाम प्राप्त करेंगे (उदाहरण के लिए कुछ फ़ाइलों वाले पेड़ के नीचे निर्देशिका), बस

find $PWD

मैं इसका उपयोग Solaris 10 पर करता हूं, जिसमें अन्य उपयोगिताओं का उल्लेख नहीं है।


1
मैंने पहली टिप्पणी पर यह टिप्पणी नहीं की; यहाँ मुख्य बात यह है कि यदि आप खोज कमांड को निरपेक्ष मार्ग देते हैं तो यह निरपेक्ष पथ में परिणाम देगा। इसलिए $ PWD का उपयोग करना वह पूर्ण पथ है जहां आप हैं इसलिए आपको आउटपुट पूर्ण रूप से मिलता है।
simbo1905

4
यदि आप भरोसा करते हैं PWD, तो आप बस इस्तेमाल कर सकते हैं $PWD/$filename
जॉनी

-Maxdepth 1 के उपयोग के साथ इस दृष्टिकोण में सुधार किया जा सकता है। यहां तक ​​कि आप इस का उपयोग कैसे करें, इसके आधार पर - संभावित सुरक्षा मुद्दों को उद्धृत करने के बारे में मत भूलना।
mc0e

1
@ जॉनी: $ पीडब्ल्यूडी / $ फ़ाइलनाम विफल हो जाता है अगर $ फ़ाइल नाम पहले से ही निरपेक्ष है।
mc0e

यदि फ़ाइल का नाम "./filename.txt" (अग्रणी बिंदु और स्लैश के साथ) दिया गया है तो यह विफल हो जाता है।
मार्क स्टोसबर्ग

15

यदि आपके पास रीडिंक या रियलपैथ उपयोगिताओं नहीं हैं, तो आप निम्नलिखित फ़ंक्शन का उपयोग कर सकते हैं जो बैश और ज़ीश में काम करता है (बाकी के बारे में निश्चित नहीं)।

abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; }

यह भी कोई नहीं फ़ाइलों के लिए काम करता है (जैसा कि अजगर कार्य करता है os.path.abspath)।

दुर्भाग्य से abspath ./../somefileडॉट्स से छुटकारा नहीं मिलता है।


1
मुझे पोर्टेबल लगता है। दूसरी ओर, एक फ़ाइल नाम पर उदाहरण के लिए टूट जाएगा जिसमें एक नई रेखा होगी।
रोमन चेप्लाकाका

1
में और सुधार करने के लिए, की जगह echo "$1"के साथ printf "%s\n" "$1"(दूसरा गूंज के साथ ही)। echoइसके तर्कों के अंदर बैकस्लैश की व्याख्या कर सकते हैं।
रोमन चेप्साकाका

फिर से, तुम सही हो! वास्तव में, zsh में इको कमांड का व्यवहार बैश से अलग है।
hluk

1
यदि तर्क में बैकस्लैश हैं, तो ईको के POSIX व्यवहार के तहत सख्ती से बोलना अपरिभाषित है। हालांकि, इसे XSI एक्सटेंशन के तहत परिभाषित किया गया है (अर्थात्, गूंज को एस्केप सीक्वेंस की व्याख्या करनी चाहिए)। लेकिन बैश और zsh दोनों POSIX अनुपालन से बहुत दूर हैं ...
रोमन Cheplyaka

क्षमा करें, लेकिन मुझे यह बात दिखाई नहीं दे रही है। मैंने पहले से ही एक स्क्रिप्ट के रूप में अधिक सुविधाओं के साथ एक उत्तर प्रदान किया है कि यह और इसे शेल स्क्रिप्ट के भीतर उपयोग करने की आवश्यकता नहीं है।
१dy

10

यहां एक zsh-only फ़ंक्शन है जो मुझे इसकी कॉम्पैक्टनेस के लिए पसंद है। यह 'ए' विस्तार संशोधक का उपयोग करता है - zshexpn (1) देखें।

realpath() { for f in "$@"; do echo ${f}(:A); done }

वाह कि एक सुंदर समाधान है !!
शेलफिश

6

आम तौर पर ऐसी कोई चीज नहीं है के रूप में एक फ़ाइल (इस बयान का अर्थ है कि सामान्य रूप में एक से अधिक है, इसलिए निश्चित लेख के उपयोग हो सकता है कि करने के लिए उचित नहीं है)। कोई भी रास्ता जो रूट "/" से शुरू होता है और कार्यशील निर्देशिका से स्वतंत्र रूप से अस्पष्टता के बिना एक फ़ाइल को डिज़ाइन करता है (उदाहरण के लिए विकिपीडिया देखें )। absolute pathabsolute path

A एक relative pathऐसा मार्ग है जिसकी व्याख्या दूसरी निर्देशिका से शुरू की जानी है। यदि यह relative pathकिसी एप्लिकेशन द्वारा हेरफेर किया जा रहा है (हालांकि जरूरी नहीं) तो यह कार्यशील निर्देशिका हो सकती है । जब यह एक निर्देशिका में एक प्रतीकात्मक लिंक में होता है, तो यह आमतौर पर उस निर्देशिका के सापेक्ष होने का इरादा होता है (हालांकि उपयोगकर्ता के मन में अन्य उपयोग हो सकते हैं)।

इसलिए एक पूर्ण पथ जड़ निर्देशिका के सापेक्ष मात्र एक मार्ग है।

पथ (निरपेक्ष या सापेक्ष) में प्रतीकात्मक लिंक शामिल हो सकते हैं या नहीं भी हो सकते हैं। यदि ऐसा नहीं होता है, तो यह लिंकिंग संरचना में परिवर्तन के लिए भी कुछ हद तक अभेद्य है, लेकिन यह आवश्यक नहीं है या यहां तक ​​कि वांछनीय भी है। कुछ लोगों को कॉल canonical path(या canonical file nameया resolved path) एक absolute pathजिसमें सभी सांकेतिक लिंक समाधान हो गया है, यानी whetever वे से जोड़ने के लिए एक रास्ता ने ले ली है। कमांड realpathऔर readlinkदोनों एक विहित पथ की तलाश करते हैं, लेकिन केवल realpathप्रतीकात्मक लिंक को हल करने के लिए परेशान करने के लिए एक निरपेक्ष पथ प्राप्त करने के लिए एक विकल्प है (विभिन्न निर्देशिका के लिए कई अन्य विकल्पों के साथ, कुछ निर्देशिका के लिए पूर्ण या सापेक्ष)।

यह कई टिप्पणियों के लिए कहता है:

  1. प्रतीकात्मक लिंक केवल तभी हल किए जा सकते हैं जब वे जो कुछ भी लिंक करने वाले हों, वह पहले से ही बनाया गया हो, जो जाहिर तौर पर हमेशा ऐसा नहीं होता है। आदेश realpathऔर readlinkउस के लिए खाते में विकल्प हैं।
  2. एक पथ पर एक निर्देशिका बाद में एक प्रतीकात्मक लिंक बन सकती है, जिसका अर्थ है कि पथ अब नहीं है canonical। इसलिए अवधारणा समय (या पर्यावरण) पर निर्भर है।
  3. आदर्श मामले में भी, जब सभी प्रतीकात्मक लिंक हल किए जा सकते हैं, तब भी canonical pathदो कारणों से एक से अधिक फ़ाइल हो सकती हैं :
    • फ़ाइल में विभाजन roको कई माउंट बिंदुओं पर एक साथ ( ) माउंट किया गया हो सकता है ।
    • फ़ाइल के लिए हार्ड लिंक हो सकते हैं, जिसका अर्थ है कि फ़ाइल कई अलग-अलग निर्देशिकाओं में मौजूद है।

इसलिए, यहां तक ​​कि बहुत अधिक प्रतिबंधात्मक परिभाषा के साथ canonical path, फ़ाइल में कई कैनोनिकल पथ हो सकते हैं। इसका मतलब यह भी है कि क्वालीफायर canonicalकुछ हद तक अपर्याप्त है क्योंकि यह आमतौर पर विशिष्टता की धारणा को दर्शाता है।

यह बाश में एक अन्य समान प्रश्न के उत्तर में विषय की एक संक्षिप्त चर्चा का विस्तार करता है : सापेक्ष दिए गए पूर्ण पथ को पुनः प्राप्त करें

मेरा निष्कर्ष यह है कि realpathबेहतर डिज़ाइन किया गया है और बहुत अधिक लचीला है readlink। उस के एकमात्र उपयोग को readlinkकवर नहीं किया जाता realpathहै, बिना विकल्प के कॉल एक प्रतीकात्मक लिंक के मूल्य को वापस करता है।


मुझे नीचा दिखाने में कोई आपत्ति नहीं है, लेकिन मुझे यह समझना पसंद है कि क्यों मैं कुछ सीख सकता हूं, या तो तकनीकी या साइट पर उचित अभ्यास के बारे में क्या माना जाता है। खैर ... कम से कम इसने मुझे स्थानीय समाजशास्त्र को बेहतर ढंग से समझने के लिए मेटा स्टैक ओवरफ्लो के साथ पंजीकरण करने के लिए प्रेरित किया । मैं इसकी सिफारिश करता हूं। - फिर भी, अगर किसी को मेरे जवाब की अनुपयुक्तता के बारे में राय है, तो मुझे दिलचस्पी है।
बबौ

1
(ए) प्रश्न का 2 + 1/2 साल पहले का वैध उत्तर है, (बी) एक रिश्तेदार पथ (जो कि मैं चाहता था) के अनुरूप एक (एकल) निरपेक्ष पथ है, हालांकि शायद आपके पास फ़ाइल के रूप में नहीं है बताया। BTW बारे में कोई टिप्पणी realpathबनाम readlinkया यहाँ तक कि सांकेतिक लिंक के बारे में मैं क्या पूछा के लिए अधिशेष है।
'18

1
दूसरी टिप्पणी: छोटे व्याख्यान की तुलना में छोटे उत्तर बहुत अधिक उपयोगी होते हैं। स्टैक ओवरफ्लो आमतौर पर विशिष्ट प्रश्न पूछने के लिए उपयोग किया जाता है।
'18

5
1- तथ्य यह है कि एक प्रश्न का लंबे समय तक एक वैध जवाब रहा है, इसका मतलब यह नहीं है कि यह बंद है। प्रश्न केवल व्यक्ति के उपयोग के लिए अभिप्रेत नहीं हैं। वास्तव में, उत्तरों के लिए बैज हैं जो मान्य उत्तर की तुलना में अधिक वोट एकत्र करते हैं। और नए उपकरणों के साथ, "सर्वश्रेष्ठ" उत्तर समय के साथ बदल सकता है। बहुत से लोग वेब खोज के माध्यम से एक्सेस किए गए पुराने उत्तरों का उपयोग करते हैं।
बबौ

1
2 - आप जोर देते हैं कि एक रिश्तेदार पथ के लिए एक (एकल) निरपेक्ष पथ है । हालांकि मैं अनुमान लगाता हूं कि "संगत" से आपका क्या मतलब है, अर्थात किसी दिए गए परिवर्तनों के माध्यम से मूल से प्राप्त पथ, आपका कथन अभी भी गलत है। एक अद्वितीय "संगत" विहित पथ है। यह शब्द canonicalसटीक रूप से परिवर्तनों के एक सेट के सापेक्ष इस विशिष्टता को दर्शाता है। लेकिन, उदाहरण के लिए, / dev / cdrom एक पूर्ण रूप से अच्छा मार्ग है, भले ही यह वास्तव में / dev / sr0 का लिंक हो। दोनों एक ही डिवाइस की ओर इशारा करते हैं। मेरा मूल उत्तर एक प्रासंगिक वेब लेख की ओर इशारा करता है।
बबौ

5

dogbane जवाब वर्णन क्या पर आ रहा है के साथ:

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"

स्पष्टीकरण:

  1. इस लिपि को तर्क के रूप में सापेक्ष मार्ग मिलता है "$1"
  2. फिर हमें उस पथ का dirname भाग मिलता है (आप इस स्क्रिप्ट में dir या फ़ाइल पास कर सकते हैं):dirname "$1"
  3. फिर हम cd "$(dirname "$1")इस सापेक्ष डायर में जाते हैं और pwdशेल कमांड चलाकर इसके लिए पूर्ण मार्ग प्राप्त करते हैं
  4. उसके बाद हम बेसमेन को पूर्ण पथ पर ले जाते हैं:$(basename "$1")
  5. अंतिम चरण के रूप में हम echoइसे

2

निर्देशिका के dirnameलिए ../और रिटर्न के लिए ट्रिप हो जाता है ./

nolan6000 के फ़ंक्शन को ठीक करने के लिए संशोधित किया जा सकता है:

get_abs_filename() {
  # $1 : relative filename
  if [ -d "${1%/*}" ]; then
    echo "$(cd ${1%/*}; pwd)/${1##*/}"
  fi
}

1
एसओ में आपका स्वागत है! छोटे परिवर्तनों और टिप्पणियों के लिए, किसी मौजूदा उत्तर में टिप्पणी जोड़ना उत्तर जोड़ने की तुलना में अधिक उपयुक्त हो सकता है, खासकर यदि यह प्रतिलिपि किए गए उत्तर में मूल उत्तर की अन्य जानकारी का बहुत अभाव है। एक बार जब आप थोड़ा और अधिक प्रतिष्ठा अर्जित कर लेते हैं, तो आप अन्य लोगों के उत्तरों में टिप्पणियां जोड़ सकते हैं। अभी के लिए, अद्वितीय, मूल्यवान प्रश्न पूछकर या अकेले खड़े रहने, अच्छे उत्तर देकर प्रतिष्ठा प्राप्त करने का प्रयास करें।
cfi

1
चूंकि आप nolan6000 के उत्तर का उल्लेख कर रहे हैं, कृपया ध्यान दें कि पोस्टर धारी ने पहले ही टिप्पणी कर दी थी कि वह nolan6000 के उत्तर को स्वीकार नहीं करेगा क्योंकि वह स्क्रिप्ट की तलाश नहीं कर रहा है। इसलिए सख्ती से अपना जवाब देने से सवाल का जवाब नहीं मिलता।
cfi

फ़ंक्शन को जोड़ा जा सकता है .profileऔर इसलिए इंटरैक्टिव उपयोग के लिए उपलब्ध है।
एडिब

यह $1एक सादे फ़ाइल नाम होने पर काम नहीं करेगा : get_abs_filename foo-> कुछ भी नहीं (या <current_dir>/foo/fooअगर fooएक निर्देशिका है)।
ivan_pozdeev 14

2

यह सवाल का जवाब नहीं है, लेकिन उन लोगों के लिए जो स्क्रिप्टिंग करते हैं:

echo `cd "$1" 2>/dev/null&&pwd||(cd "$(dirname "$1")";pwd|sed "s|/*\$|/${1##*/}|")`

यह सही ढंग से / ..// आदि को संभालता है। मैं भी OSX पर काम करने लगता है


2

मैंने अपने सिस्टम पर निम्नलिखित स्क्रिप्ट रखी है और मैं इसे बैश उर्फ ​​के रूप में कहता हूं, जब मैं जल्दी से वर्तमान डायर में एक फ़ाइल के लिए पूर्ण पथ को हथियाना चाहता हूं:

#!/bin/bash
/usr/bin/find "$PWD" -maxdepth 1 -mindepth 1 -name "$1"

मुझे यकीन नहीं है कि क्यों, लेकिन, ओएस एक्स पर जब एक स्क्रिप्ट "$ PWD" द्वारा बुलाया जाता है, तो पूर्ण पथ पर फैलता है। जब कमांड लाइन पर खोज कमांड को बुलाया जाता है, तो यह नहीं होता है। लेकिन यह वही करता है जो मैं चाहता हूं ... आनंद लें।


$PWDहमेशा वर्किंग डाइरेक्टरी का निरपेक्ष पथ होता है। इसके अलावा, findस्लैश बर्दाश्त नहीं करेंगे, इसलिए आप इस सवाल का जवाब नहीं दे रहे हैं। आप जो करना चाहते हैं, उसे करने का एक तेज़ तरीका हैecho "$PWD/$1"
एडम काटज़

2

यदि आप केवल बिल्डिंस का उपयोग करना चाहते हैं तो सबसे सरल है:

find `pwd` -name fileName

टाइप करने के लिए केवल एक अतिरिक्त दो शब्द, और यह सभी यूनिक्स सिस्टम, साथ ही साथ ओएसएक्स पर काम करेगा।


मैं -maxdepth 1पहले जोड़ -nameदूंगा (फ़ाइल को चालू निर्देशिका में है)। इसके बिना यह pwd के किसी भी उपनिर्देशिका में फाइलों के साथ काम करेगा, लेकिन दूसरों के साथ नहीं।
वाल्टर ट्रॉस

वास्तव में आप सही हैं, यह प्रश्न निर्दिष्ट करता है कि फ़ाइल वर्तमान निर्देशिका में होगी। आपका क्या मतलब है "लेकिन दूसरों के साथ नहीं"?
Arj

मेरा मतलब है findकि डायरेक्टरी ट्री के बाहर एक फाइल नहीं मिलेगी pwd। जैसे, यदि आप कोशिश करते हैं find . -name ../existingFile, तो यह विफल हो जाता है।
वाल्टर ट्रॉस

काफी उचित है, हाँ यह मान लेंगे कि आप अपने cwd (मूल प्रश्न के अनुसार), या कहीं भी अपने cwd ट्री (मूल प्रश्न में नहीं) के रूप में एक फ़ाइल का पूरा पथ मुद्रित करना चाहते हैं।
Arj

1
#! /bin/bash

file="$@"
realpath "$file" 2>/dev/null || eval realpath $(echo $file | sed 's/ /\\ /g')

यह कमियों के लिए बनाता है realpath, इसे एक शेल स्क्रिप्ट में संग्रहीत करें fullpath। अब आप कॉल कर सकते हैं:

$ cd && touch a\ a && rm A 2>/dev/null 
$ fullpath "a a"
/home/user/a a
$ fullpath ~/a\ a
/home/user/a a
$ fullpath A
A: No such file or directory.

क्या हल करता है? realpath "foo bar"-> /home/myname/foo bar। यदि आप कमांड लाइन के तर्कों को उद्धृत करने के लिए परेशान नहीं हो सकते, तो यह गलत नहीं realpathहै।
ivan_pozdeev

सहमत, यह एक सुविधा आवरण के अधिक है।
शेलफिश

1

रूबी में पूर्ण पथ प्राप्त करने का एक विकल्प :

realpath() {ruby -e "require 'Pathname'; puts Pathname.new('$1').realpath.to_s";}

कोई तर्क (वर्तमान फ़ोल्डर) और सापेक्ष और पूर्ण फ़ाइल या फ़ोल्डर पथ के साथ कार्य करता है।


0

होमब्रे के साथ उत्तर दें

realpathसबसे अच्छा जवाब है, लेकिन अगर आपने इसे स्थापित नहीं किया है, तो आपको पहले चलना चाहिए brew install coreutilsजो बहुत सारे भयानक कार्यों के साथ कोर्यूटिल स्थापित करेगा । एक कस्टम फ़ंक्शन लिखना और इसे निर्यात करना बहुत अधिक काम है और कुछ इस तरह की त्रुटि के लिए जोखिम है, यहां दो लाइनें हैं:

$ brew install coreutils
$ realpath your-file-name.json 

-1

हे दोस्तों मुझे पता है कि यह एक पुराना धागा है, लेकिन मैं इसे किसी और के संदर्भ में पोस्ट कर रहा हूं जो मेरे जैसे इस पर गए थे। यदि मैं प्रश्न को सही ढंग से समझता हूं, तो मुझे लगता है कि locate $filenameकमांड। यह आपूर्ति की गई फ़ाइल का पूर्ण पथ प्रदर्शित करता है, लेकिन केवल अगर यह मौजूद है।


4
locateनाम से फ़ाइलों / रास्तों की खोज करने के लिए एक उपयोगिता है। यह काम कर सकता है, लेकिन अन्य मैच भी खोज सकता है और updatedbपहले रूट के रूप में कॉल किए बिना एक मौजूदा फ़ाइल नहीं मिल सकती है ।
१dy
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.