प्रत्येक पैरामीटर से ट्रेलिंग स्लैश को हटाने का सबसे सरल तरीका क्या है?


97

'$ @ ’सरणी में प्रत्येक पैरामीटर से ट्रेलिंग स्लैश को हटाने का सबसे सरल तरीका क्या है, ताकि rsyncनिर्देशिकाओं को नाम से कॉपी किया जा सके?

rsync -a --exclude='*~' "$@" "$dir"

स्पष्टीकरण के लिए शीर्षक को बदल दिया गया है। टिप्पणियों को समझने और कई अनुगामी स्लैशों के बारे में जवाब देने के लिए संपादित इतिहास देखें।


जवाबों:


160

आप ${parameter%word}विस्तार का उपयोग यहां कर सकते हैं । यहाँ एक सरल परीक्षण लिपि है जो व्यवहार को प्रदर्शित करती है:

#!/bin/bash

# Call this as:
#   ./test.sh one/ two/ three/ 
#
# Output:
#  one two three

echo ${@%/}

35
+1: अत्यधिक पांडित्यपूर्ण होना, जो एकल स्लैश को हटा देगा, सभी अनुगामी स्लैश नहीं। ट्रेलिंग स्लैश की किसी भी संख्या को हटाने के लिए:shopt -s extglob; echo "${@%%+(/)}"
ग्लेन जैकमैन

24
चेतावनी: आप सभी मामलों में ट्रेलिंग स्लैश को दूर नहीं करना चाह सकते हैं। यदि "/" एक तर्क के रूप में आपूर्ति की जाती है, तो पीछे चल रहे स्लैश को हटा दिया जाएगा ... दुर्भाग्यपूर्ण परिणाम।
गॉर्डन डेविसन

13
PROTIP: tr -s /बार-बार होने वाले स्लैश को दूर करने के लिए वैरिएबल रेगेक्स के साथ मिलाएं और उसके बाद ट्रेलिंग स्लैश को हटा दें। जैसेDIR=$(echo //some///badly/written///dir////// | tr -s /); DIR=${DIR%/}
डेव

1
वास्तव में? एक बैश प्रॉम्प्ट पर, दौड़ें set -- one///// two// three four/; shopt -s extglob; echo "${@%%+(/)}"और मुझे बताएं कि आप क्या देखते हैं
ग्लेन जैकमैन

1
@twalberg मैं "प्रोटिप्स" की सराहना करता हूं जो टिप्पणी थ्रेड्स में ओपी के प्रश्न का सिर्फ वैकल्पिक उत्तर नहीं हैं।
काइल स्ट्रैंड

39

स्वीकृत उत्तर वन ट्रेलिंग स्लैश को ट्रिम कर देगा।

एकाधिक ट्रेलिंग स्लैश को ट्रिम करने का एक तरीका इस प्रकार है:

VALUE=/looks/like/a/path///

TRIMMED=$(echo $VALUE | sed 's:/*$::')

echo $VALUE $TRIMMED

कौन से आउटपुट:

/looks/like/a/path/// /looks/like/a/path

1
अपने चरों को उद्धृत करना न भूलें, यदि उनमें TRIMMED=$(echo "$VALUE" | sed 's:/*$::')
व्हॉट्सएप हो

1
वास्तव में यह $()निर्माण के अंदर आवश्यक नहीं है । हालाँकि यह हानिरहित भी है :) इसलिए दोहरे उद्धरण चिह्नों का उपयोग करना शायद एक अच्छा अभ्यास है, "$VALUE"इसलिए आपको यह निर्णय नहीं लेना है कि कब और कब दोहरे उद्धरण चिह्नों का उपयोग नहीं करना है।
क्रिस जॉनसन

किसी भी तरह से इसे पहले कब्जा के साथ गठबंधन? मैं प्रोटोकॉल स्ट्रिप करना चाहता हूं और (यदि मौजूद है) URL से स्लैश ट्रेस कर रहा हूं, लेकिन echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)/*$|\1|'काम नहीं करता है (क्योंकि कैप्चर ग्रुप ट्रेलिंग स्लैश के साथ-साथ मेरे अनुमान से मेल खाता है)। मैं इसे दो आदेशों के साथ कर सकता हूं: echo "https://www.example.com/foo/" | sed -e 's|https*://\(.*\)$|\1|' -e 's|/*$||'लेकिन सोचता हूं कि क्या यह एक के साथ किया जा सकता है?
एडम

इस जवाब ने मेरे लिए एक बहुत बड़ी इनपुट फ़ाइल के साथ बेहतर काम किया। एक साधारण sed 's:/*$::' < in.txt > out.txtसेकंड में काम करता है
मिशेल

21

यह मेरे लिए काम करता है: ${VAR%%+(/)}

जैसा कि यहाँ वर्णित है http://wiki.bash-hackers.org/syntax/pattern

शेल विकल्प को सेट करने की आवश्यकता हो सकती है। मैं इसे मेरे लिए सक्षम नहीं देख सकता, लेकिन यह अभी भी काम करता है


2
एक सेटिंग को क्वेरी करने के लिए: shopt extglobकोई विकल्प नहीं
ग्लेन जैकमैन

यह विस्तारित पैटर्न भाषा है और आपको इसे सेट करना होगाextglob
पहुंचें

1
यह मैक ओएस एक्स के बिलिन बैश पर काम नहीं करता है। शॉन ब्राइट द्वारा उपरोक्त समाधान इस प्रकार है:${VAR%/}
एलेक जैकबसन

13

realpathदिए गए मार्ग को हल करता है। अन्य बातों के अलावा यह ट्रेलिंग स्लैश को भी हटाता है। -sनिम्नलिखित simlinks को रोकने के लिए उपयोग करें

DIR=/tmp/a///
echo $(realpath -s $DIR)
# output: /tmp/a

1
यह पिछले एक को छोड़कर रास्ते में सभी नोड्स की आवश्यकता है। यदि उपयोगकर्ता कुछ गैर-अस्तित्व पथ में फेंकता है, realpathतो विफल हो जाएगा।
Livy

2
@ लिवी realpath --canonicalize-missingपथ के किसी भी गैर-मौजूदा हिस्से के साथ बिल्कुल सही ढंग से काम करता है
mauizm

और realpath कुछ प्लेटफार्मों पर गायब है :-(
मार्क रिबाऊ

8

FYI करें, मैंने .bash_profileSO पर मिले उत्तरों के आधार पर इन दोनों कार्यों को अपने साथ जोड़ा । जैसा कि क्रिस जॉनसन ने कहा, सभी जवाब ${x%/}केवल एक स्लैश को हटाने का उपयोग करते हैं , ये कार्य वही करेंगे जो वे कहते हैं, आशा है कि यह उपयोगी है।

rem_trailing_slash() {
    echo "$1" | sed 's/\/*$//g'
}

force_trailing_slash() {
    echo "$(rem_trailing_slash "$1")/"
}

4

में zsh आप उपयोग कर सकते :aसंशोधक।

export DIRECTORY='/some//path/name//'

echo "${DIRECTORY:a}"

=> /some/path/name

यह काम करता है realpathलेकिन तर्क के रूप में लापता फ़ाइलों / निर्देशिकाओं के साथ विफल नहीं होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.