निर्देशिका में फ़ाइलों के लिए, केवल इको फ़ाइल नाम (कोई रास्ता नहीं)


99

अगर मैं एक लूप के लिए एक निर्देशिका को दर्ज करता हूं, तो मैं केवल फ़ाइल के फ़ाइल नाम को गूँजने के बारे में कैसे जा सकता हूं?

for filename in /home/user/*
do
  echo $filename
done;

फ़ाइल नाम के साथ पूरा रास्ता खींच देगा। मुझे सिर्फ फ़ाइल का नाम चाहिए।

जवाबों:


166

यदि आप एक देशी bashसमाधान चाहते हैं

for file in /home/user/*; do
  echo "${file##*/}"
done

उपरोक्त पैरामीटर विस्तार का उपयोग करता है जो शेल का मूल है और बाहरी बाइनरी जैसे कॉल की आवश्यकता नहीं हैbasename

हालाँकि, क्या मैं सिर्फ उपयोग करने का सुझाव दे सकता हूं find

find /home/user -type f -printf "%f\n"

9
अच्छा उत्तर। पैरामीटर विस्तार के बारे में अधिक जानने में रुचि रखने वालों के लिए: wiki.bash-hackers.org/syntax/pe#substring_removal
डग ड

1
-प्रिंट: अज्ञात प्राथमिक या ऑपरेटर => unix.stackexchange.com/a/272493/72893
नोबिता

2
"नाम के साथ रिक्त स्थान के साथ फ़ाइल नाम का समर्थन ${file##*/}करने के "${file##*/}"लिए बदलने पर विचार करें ।
विनयुनुच्स 2 यूनिक्स

इको "$ {फ़ाइल ## * /}" एक रिक्त स्ट्रिंग देता है
एलेसेंड्रो सी

48

बस उपयोग करें basename:

echo `basename "$filename"`

मामले की जरूरत है मामले में $ फ़ाइल नाम में रिक्त स्थान होते हैं।


3
पैरामीटर विस्तार का उपयोग करने के लिए बेहतर है, बाहरी बायनेरिज़ को कॉल की आवश्यकता नहीं है।
घेराबंदी

5
Btw, `` पदावनत है। $()ओली ने किया उपयोग करने के लिए बेहतर
SiegeX

1
इस पुराने उत्तर पर टिप्पणी करने के लिए क्षमा करें, लेकिन आधार स्थान के साथ फ़ाइलों के लिए सही ढंग से काम नहीं करेगा। उदाहरण: लोक निर्माण विभाग के उत्पादन: /test 1, basename $(pwd)उत्पादन: test। ओएस एक्स और उबंटू सर्वर (14.04) पर परीक्षण किया गया। मूल बश समाधान, @SiegeX के रूप में अनुशंसित है, जो मेरे लिए काम कर रहा है।
Marko Grešak

basename "$(pwd)"इसके बजाय @ MarkoGrešak का उपयोग करें ।
यंगफ्रॉग

@YoungFrog इनपुट के लिए धन्यवाद, लेकिन यह 9 महीने पहले था। साथ $PWDही कमांड को चलाने के बजाय वेरिएबल का उपयोग करना बेहतर होगा ।
Marko Grešak

16

उपयोग करें basename:

echo $(basename /foo/bar/stuff)

आप क्यों इस्तेमाल करते हैं echo? basenameपहले से ही परिणाम प्रिंट करता है। echoयहां तक ​​कि अगर आप उपधारा को उद्धृत नहीं करते हैं, तो परिणाम को रोक सकते हैं। उदाहरण: echo $(basename path/with\ \ spaces)गलत तरीके से प्रिंट with spaces(केवल एक स्थान)।
सोकोवई

8

एक और तरीका यह है lsकि एक डायरेक्टरी के भीतर फाइल लिस्ट को पढ़ते समय इस्तेमाल किया जाए ताकि आप जो चाहें वो दे सकें, यानी "सिर्फ फाइल नेम / एस"। के रूप में पूर्ण फ़ाइल पथ को पढ़ने के लिए और उसके बाद लूप के शरीर में "फ़ाइल नाम" घटक को निकालने के लिए।

नीचे दिए गए उदाहरण जो आपके मूल का अनुसरण करते हैं:

for filename in $(ls /home/user/)
do
  echo $filename
done;

यदि आप स्क्रिप्ट को फ़ाइलों के समान निर्देशिका में चला रहे हैं, तो यह बस बन जाता है:

for filename in $(ls)
do
  echo $filename
done;

1
lsइसमें कोई भी डॉटफ़ाइल्स शामिल है जहाँ *विस्तार आमतौर पर नहीं होता है। इसके अलावा for f in $(...) ...अगर कोई फ़ाइल नाम में व्हॉट्सएप शामिल है, जब तक कि आप IFS सेट नहीं करते, तब तक विफल हो सकता है, जब तक कि किसी फ़ाइलनाम में ग्लोब चार नहीं है, जब तक कि आप -f / -o noglob को सेट नहीं करते हैं, और सिस्टम या शेल के आधार पर echoयदि कोई फ़ाइल नाम हाइफ़न + अक्षर या बैकस्लैश है तो विफल हो सकता है। OTOH केवल ls -1 /path/to/dirसभी अपने आप में एक रेखा पर प्रत्येक फ़ाइलनाम को मज़बूती से प्रिंट करता है, जो डॉटफ़ाइल्स अंतर को मापता है।
dave_thompson_085

0

यदि आप केवल नाम चाहते हैं:

for file in /home/user/*; do       
  f=$(echo "${file##*/}");
  filename=$(echo $f| cut  -d'.' -f 1); #file has extension, it return only filename
  echo $filename
done

cutकमांड के बारे में अधिक जानकारी के लिए यहां देखें ।

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