'ls -1': बिना विस्तार के फ़ाइल नाम कैसे सूचीबद्ध करें


24

ls -1 मेरे तत्वों को इस तरह सूचीबद्ध करता है:

foo.png
bar.png
foobar.png
...

मैं चाहता हूँ कि यह बिना .pngपसंद के सूचीबद्ध हो:

foo
bar
foobar
...

(dir में केवल .pngफ़ाइलें हैं)

क्या कोई मुझे बता सकता है कि grepइस मामले में कैसे उपयोग किया जाए?

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


36
आप इस तरह अनुरोध के साथ सावधान रहना चाहते हैं। लिनक्स में फ़ाइल नाम एक्सटेंशन नहीं है। लिनक्स में फ़ाइलनाम हैं जो .उनमें शामिल हो सकते हैं या नहीं भी हो सकते हैं। हालांकि सम्मेलन के साथ अपनी फ़ाइलों को नाम देने का कहना है .pngअंत में, वहाँ कोई कारण नहीं क्यों मैं एक PNG फ़ाइल नामित नहीं हो सकता है foo.zipया my.picture.20160518या बस mypic
हाइमी

2
@ मुझे पता है, लेकिन उस फ़ोल्डर में मेरे तत्वों को अंत में .png के साथ नाम दिया गया है।
कॉलिन

14
"एक्सटेंशन" क्या है? यह यूनिक्स फ़ाइल नामकरण का हिस्सा नहीं है; यह वीएमएस / एनटी / विंडोज से जो भी हो, कैरीओवर है। और तुम नौजवान मेरे लॉन को भी बंद कर दो। :)
mpez0

28
चलो इस पर काबू नहीं। OS एक्सटेंशन को केवल फ़ाइल नाम का हिस्सा मानता है, लेकिन बहुत सारे यूनिक्स प्रोग्राम कंपाइलर से GUI तक उन पर ध्यान देते हैं। अवधारणा सबसे निश्चित रूप से यूनिक्स के लिए विदेशी नहीं है।
एलेक्सिस

1
आमतौर पर यह सुझाव दिया जाता है कि आउटपुट को पार्सls करने से बचने के लिए और आउटपुट को पाइप करने के लिए lsऔर find, मुख्य रूप से क्योंकि newlineफ़ाइल नाम में टैब टैब में लाइक करने की संभावना है । यदि फ़ाइल नाम The new art of working on .png\NEWLINE files and other formatsप्रस्तावित समाधान के कई हैं तो समस्याएं पैदा होंगी।
हस्त्तूर

जवाबों:


41

आपको इस नौकरी के लिए केवल शेल की आवश्यकता है।

POSIXly:

for f in *.png; do
    printf '%s\n' "${f%.png}"
done

के साथ zsh:

print -rl -- *.png(:r)

4
इसकी कोई आवश्यकता नहीं है printf; echo ${f%.png}पर्याप्त होगा।
डेविड कॉनरेड

11
@Conrad: इको का उपयोग कुछ मामलों में ठीक से काम नहीं करेगा, अगर फ़ाइल का नाम डैश से शुरू होता है या इसमें अनुक्रम बच जाता है।
congongl

3
@DavidConrad: यह भी देखें unix.stackexchange.com/a/65819/38906
cuonglm

35
ls -1 | sed -e 's/\.png$//'

sedआदेश हटा देगा (यह है कि, यह खाली स्ट्रिंग के साथ बदलता है) किसी भी स्ट्रिंग .pngमें पाया अंत एक फ़ाइल नाम की।

इस तरह .से बच जाता \.है कि इसे रीजेक्सपी के बजाय sedशाब्दिक .चरित्र के रूप में व्याख्या की जाती है .(जिसका अर्थ है किसी भी चरित्र से मेल खाता है)। $तो यह मेल नहीं खाता, अंत लाइन लंगर है .pngएक फ़ाइल नाम के बीच में।


4
मुझे लगता है कि ओपी किसी भी विस्तार को छीनना चाहता है , लेकिन शायद केवल "अंतिम एक"। तो शायद अपने अन्यथा अच्छे उत्तर को संशोधित करें:sed 's/\.[^.]*$//'
ओथियस १16

1
हाँ, कि regexp उस मामले में काम करेगा ... लेकिन अगर ओपी कि चाहता है, वे कहते हैं चाहिए ताकि बजाय विशेष रूप से कहा कि वे "चाहते हैं कि उसे .png बिना सूचीबद्ध"
कैस

4
यह -1आवश्यक नहीं है, यहां डिफ़ॉल्ट होना चाहिए।
जुलियागेरे

3
@jlliagre मैं कैस से सहमत हूं -1जिसे निर्दिष्ट किया जाना चाहिए। यह केवल डिफ़ॉल्ट है जब पाइप चालू होता है, जो कुछ के लिए एक छिपा हुआ आश्चर्य है। तो यह स्पष्ट रूप से समझने में मदद करता है। मैं अपनी स्क्रिप्ट में भी ऐसा करता हूं इसलिए मुझे पता है कि मैं किस तरह के आउटपुट की उम्मीद कर रहा हूं।
ओथियस

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

16

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

for i in *; do echo "${i%.png}"; done

grepजब आप मैच ढूंढने की कोशिश कर रहे हों , तो उसके लिए पहुंचना चाहिए , न कि उसको हटाने / प्रतिस्थापित करने के लिए sedअधिक उपयुक्त है:

find . -maxdepth 1 -name "*.png"  | sed 's/\.png$//'

एक बार जब आप तय करते हैं कि आपको अपनी PNG फ़ाइलों में ऑर्डर लाने के लिए कुछ उपनिर्देशिकाएँ बनाने की आवश्यकता है, तो आप इसे आसानी से बदल सकते हैं:

find . -name "*.png"  | sed 's/\.png$//'

एलएस -1 | sed 's / .png //' बढ़िया काम करता है। धन्यवाद!
कॉलिन

find पाइप के sedसमाधान में कुछ समस्याएं पेश करता है, तो आप कुंजी (के साथ एक फ़ाइल पा सकते हैं .png) नाम के एक भाग के रूप में और सिर्फ एक नई पंक्ति वर्ण से पहले। यह पाइप से बचने और के उत्पादन में पार्स करने के लिए बेहतर है findया lsयह अक्सर अच्छी तरह से छिपा आश्चर्य ... (कुछ शब्दों और संदर्भ जवाब में और अधिक) सुरक्षित रखता है,।
हस्त्तूर

शायद आखिरी उदाहरण में findकुछ की जगह echo। स्पष्ट नहीं है कि findवहां क्या उद्देश्य है और परिणाम निर्देशिका संरचना पर निर्भर करता है (यानी यदि आपके पास निर्देशिका है files.png)

@BroSlow कुछ अधिक समझदार के लिए अद्यतन किया गया।
एंथन

13

मैं basename(GNU कार्यान्वयन मानकर) जाऊंगा :

basename --suffix=.png -- *.png

ध्यान दें कि यदि आप इसे एक पाइप में उपयोग करना चाहते हैं, तो आपको एनयूएल-अलग (न्यूलाइन-अलग-अलग) आउटपुट के उत्पादन के लिए जीएनयू बेसनैम -z(या --zero) विकल्प का उपयोग करने में मदद मिल सकती है ।
टोबी स्पाइट

11

एक और बहुत ही समान उत्तर (मुझे आश्चर्य है कि यह विशेष संस्करण अभी तक सामने नहीं आया है) है:

ls | sed -n 's/\.png$//p'
  • आपको -1विकल्प की आवश्यकता नहीं है ls, क्योंकि lsमान लिया जाता है कि यदि मानक आउटपुट टर्मिनल नहीं है (यह एक पाइप है, तो इस मामले में)।
  • -nकरने के लिए विकल्प sedका अर्थ है 'डिफ़ॉल्ट रूप से लाइन मुद्रित नहीं है'
  • /pप्रतिस्थापन साधन के अंत में विकल्प '... और अगर एक प्रतिस्थापन बनाया गया था इस लाइन प्रिंट'।

इसका शुद्ध प्रभाव केवल उन लाइनों को प्रिंट करना है .png, जो .pngहटाए जाने के साथ समाप्त होती हैं । यही है, यह भी ओपी के सवाल के मामूली सामान्यीकरण को पूरा करता है, जहां निर्देशिका में केवल .pngफाइलें नहीं होती हैं ।

sed -nतकनीक जहां अन्यथा ग्रेप का उपयोग कर सकते + sed अक्सर मामलों में उपयोगी है।


मुझे पसंद है कि आप अपना जवाब लिखने के लिए कैसे देखभाल करते थे। यह समाधान नए नाम सहित फाइलनामों के साथ समस्याएं पेश करेगा , यह नाम के पहले भाग को प्रिंट नहीं करेगा। इससे भी अधिक अगर यह .pngन्यूलाइन चार से पहले कुंजी ( ) के साथ एक नास्टियर है : तो उस स्थिति में आप उस हिस्से को पींग के बिना प्रिंट करेंगे, केवल पिछले भाग को मिटाकर नहीं। पार्स (और पाइप) के उत्पादन से बचने के लिए इसे अक्सर सुगरगाइड किया जाता है lsक्योंकि समस्याओं को वहीं छिपाया जा सकता है जहां आप सोच नहीं रहे हैं ...
हस्त्तूर

2
@Hastur आप सही हैं, सिद्धांत रूप में, और प्रसिद्ध पृष्ठ नहीं के बारे में ls पार्स पैथोलॉजिकल फ़ाइलनाम सौंपते समय आगे की समस्याओं (और समाधान) को सूचीबद्ध करता है। लेकिन सबसे अच्छा तरीका है कि पैथोलॉजिकल फिलामेंट्स (दोह!) से बचने का सबसे अच्छा तरीका है ; और यदि आप नहीं कर सकते हैं, या यदि आप उनके खिलाफ मजबूत होना चाहिए, तो या तो का उपयोग करें findया - संभवतः बेहतर - shउन्हें प्रबंधित करने की तुलना में अधिक शक्तिशाली भाषा का उपयोग करें (तथ्य यह है कि सब कुछ sh कर सकते हैं इसका मतलब यह नहीं है कि यह सबसे अच्छा विकल्प है प्रत्येक मामला)। शेल को पहले प्रयोज्य के लिए डिज़ाइन किया गया है।
नॉर्मन ग्रे

मैं सहमत हूं, सिद्धांत रूप में, प्रयोज्य के बारे में, लेकिन यह संस्करण तब विफल हो जाता है जब आपके पास प्रत्येक नईलाइन के साथ फ़ाइल नाम होता है। यह आसानी से किसी का ध्यान नहीं जा सकता है, उदाहरण के लिए, जब आप एक जीयूआई में एक पीडीएफ से एक पंक्ति को कॉपी और पेस्ट करते हैं, तो आप केवल पैथोलॉजिकल फाइलनेम से बचने के लिए सोचते हैं ।
हस्त्तूर

इसके अलावा IMHO यह पार्स करने के लिए शुरू करने के लिए आसान है ls, लेकिन यह भविष्य की समस्याओं से दूर है। अक्सर हम स्क्रिप्ट बनाते हैं जो हम बाद में उपयोग करेंगे, जब हम पहले से ही अपनी सीमा भूल जाएंगे ... (यह मानव है, यह सामान्य है)। मैंने एक उदाहरण का प्रस्ताव किया find( -execयदि और पाइप के बिना), भले ही मैं एक बेहतर (क्योंकि शुद्ध खोल) क्यूंग्लम के एक , ठोस और पॉज़िक्स अनुपालन का जवाब देता हूं
हस्त्तूर

@ हस्तूर: भविष्य की समस्याएँ वैसे भी पैदा होंगी। सिस्टम में बहुत सी चीजें नईलाइनों वाली फाइलों के मुकाबले मजबूत नहीं हैं। उदाहरण के लिए उपयोग करने का प्रयास locateया makeउन पर।
रीइनियरिएपोस्ट

8

आप ऐसा करने के लिए केवल BASH कमांड का उपयोग कर सकते हैं (बिना किसी बाहरी टूल के)।

for file in *; do echo "${file%.*}"; done 

यह तब उपयोगी होता है जब आप बिना / usr / bin के होते हैं और इस तरह filenames के लिए अच्छा काम करते हैं ।is.image.png और सभी एक्सटेंशन के लिए।


6

पार्स lsया पाइप करना सुरक्षित नहीं है find[ 1 , 2 ]

यह (और पाइप के लिए) पार्स करने के लिए सुरक्षित के उत्पादन में नहीं है lsया findजिसका मुख्य कारण यह संभव खोजने के लिए, फ़ाइल नाम के रूप में गैर सामान्य पात्रों न्यू लाइन , टैब ... यहाँ एक शुद्ध खोल चक्र काम करेंगे [ cuonglm ]
यहां तक ​​कि विकल्प के साथ पाइप नहीं किया गया findकमांड काम करेगा:-exec

find ./*.png  -exec  basename {} .png  \;

अपडेट / नोट्स : आप find .छिपी हुई फ़ाइलों के लिए भी खोज करने के लिए उपयोग कर सकते हैं , या find ./*.pngकेवल छिपे हुए नहीं प्राप्त करने के लिए। find *.png -exec ...आपके पास उस स्थिति में समस्या हो सकती है जब वह नाम की एक फ़ाइल मौजूद थी .pngक्योंकि खोज उसे एक विकल्प के रूप में मिल जाएगी। आप के -maxdepth 0रूप में नामित निर्देशिकाओं में उतरने से बचने के लिए जोड़ सकते हैं Dir_01.png, या find ./*.png -prune -exec ...जब maxdepth की अनुमति नहीं है (धन्यवाद स्टीफन)। यदि आप उन निर्देशिकाओं को सूचीबद्ध करने से बचना चाहते हैं जिन्हें आपको विकल्प जोड़ना चाहिए -type f(जो अन्य प्रकार की गैर-नियमित फ़ाइलों को भी बाहर कर देगा)। manसभी उपलब्ध विकल्पों के बारे में अधिक संपूर्ण पैनोरमा के लिए इसे एक नज़र दें , और बेहतर पोर्टेबिलिटी के लिए पॉज़िक्स कंप्लेंट होने पर जांचना याद रखें।

कुछ शब्द और

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

The new art of working on .png
files and other formats.

यदि आप परीक्षण करना चाहते हैं, तो आप इस तरह से कमांड के साथ फाइल नाम बना सकते हैं

touch "A file with two lines"$'\n'"and This is the second.png"
touch "The new art of working on .png"$'\n'"files and other formats.png"

गैर प्रिंट करने योग्य पात्रों के बजाय सरल /bin/ls *pngआउटपुट होगा?

A file with two lines?and This is the second.png
The new art of working on .png?files and other formats.png

सभी मामलों जो आप करेंगे में में पाइप उत्पादन का lsया findनिम्न आदेश को समझने के लिए करता है, तो वर्तमान लाइन एक नया से आता है कोई संकेत होगा फ़ाइल नाम या अगर यह एक प्रकार है न्यू लाइन मिसाल में चरित्र फ़ाइल नाम । एक बुरा नाम वास्तव में, लेकिन अभी भी एक कानूनी।

एक खोल पैरामीटर-विस्तार के साथ एक खोल चक्र, ${parameter%word}, के साथ दोनों संस्करण में printfया echoकाम करेंगे [ cuonglm ], [ Anthon1 ]

for f in *.png; do printf "%s\n" "${f%.png}" ; done

शेल पैरामीटर विस्तार के मैन पेज से [ 3 ]

$ {पैरामीटर% शब्द}
$ {पैरामीटर %% शब्द}

... विस्तार का परिणाम सबसे छोटे मिलान पैटर्न ('%' केस) या सबसे लंबे मिलान पैटर्न ('%%' केस) के साथ पैरामीटर का मान हटा दिया गया है।


आपके findआदेश के परिणाम भी थोड़े परिवर्तनशील हैं (उदाहरण के लिए अगर कोई निर्देशिका कहा जाता है files.png)

1
प्रिय @BroSlow, जब मैंने ऊपर उत्तर लिखा था, तो मैंने उस पल में मौजूद अन्य वेरिएंट के 13 (सभी) को कमांड लाइन द्वारा, एक स्क्रिप्ट में, एक शेल इनवॉइस के तर्क के रूप में लॉन्च किया था। कृपया ऐसा ही करें और मुझे बताएं कि क्या वे आपकी अपेक्षा के अनुरूप व्यवहार करते हैं। मैंने अपना परीक्षण bash 4.3.110.5.7-4, डैश के साथ (जब आवश्यक हो) 5.0.2 किया। आप इस पोस्ट को पढ़ने के लिए बेझिझक हैं जो कुछ और जोड़ता है। मैं के नोट के बारे में सहमत पाइप के उत्पादन में find, यह मैं के लिए स्पष्ट रूप से सुझाव दिया-exec है, और मैं शीर्षक में लिखा था। :-)
हस्त्तूर

विकी को फिर से पढ़ें। मुझे अभी भी लगता है कि आपको अपने उदाहरण में पाइप करने की आवश्यकता है, क्योंकि यहां पर चर्चा की जा रही है। और अधिकांश आधुनिक संस्करणों के lsलिए कोई मुद्दा नहीं है जब भी आउटपुट पाइप या पुनर्निर्देशित किया जाता है, लेकिन जैसा कि विकी में उल्लेख किया गया है, यह सभी के लिए काम नहीं कर सकता है। अधिकांश को केवल ?विशेष वर्णों के स्थान पर सम्मिलित किया जाएगा जब आउटपुट टर्मिनल पर भेजा जाता है। यानी करो echo *.png | od -cऔर ls *.png | od -c। नईलाइन समस्या कोई समस्या नहीं है ls, यह किसी भी कमांड के साथ एक मुद्दा है जो पाइप के दोनों ओर समाप्त नहीं होता है।

1
printf "${f%.png}\n"गलत है। पहला तर्क प्रारूप है, आपको वहां चर डेटा का उपयोग नहीं करना चाहिए। यहां तक ​​कि DoS भेद्यता के रूप में भी देखा जा सकता है ( %1000000000s.pngउदाहरण के लिए फ़ाइल के साथ प्रयास करें )।
स्टीफन चेजेलस

आपको आवश्यकता होगी find ./*.png -prune -exec...या आपको फ़ाइल नाम से शुरू होने वाली -(और प्रकार निर्देशिका की फ़ाइलें, ध्यान दें कि -maxdepthपोर्टेबल नहीं है) के साथ समस्या होगी
स्टीफन चेज़लस

4

क्या यह पर्याप्त नहीं था?

ls -1 | sed 's/\.png//g'

या सामान्य तौर पर, यह

ls -1 | sed 's/\.[a-z]*//g'

सभी एक्सटेंशन निकाल देंगे


यह था, लेकिन अन्य समाधान भी काम करते हैं।
कॉलिन

मेरे कहने का मतलब है, आपका प्रश्न ls -1 से शुरू हुआ, इसलिए ls -1 को ऐसा करना चाहिए। :)
रोहेल अब्बास

यह -1आवश्यक नहीं है, यहां डिफ़ॉल्ट होना चाहिए।
जुलियागेरे

@ रोहेल अब्बास लेकिन हर सिस्टम में सेड नहीं लगा है?
कॉलिन

1
वास्तव में, लेकिन lsयह वैसे भी उस विकल्प के बिना होता है जब इसका उत्पादन टर्मिनल नहीं हो रहा है, जो कि यहां मामला है।
जुलियाग्रे

3

उपयोग करें rev:

ls -1 | rev | cut -f 2- -d "." | rev

revसभी तारों (लाइनों) को उलट देता है; आपने पहले के बाद सब कुछ काट दिया। ' और अवशेष को फिर से उलट देता है।

यदि आप grep'अल्मा' चाहते हैं :

ls -1 | rev | cut -f 2- -d "." | rev | grep 'alma'

यह -1आवश्यक नहीं है, यहां डिफ़ॉल्ट होना चाहिए।
जुलियागेरे

2
यह एक फ़ाइल नाम पर बुरी तरह से विफल रहता हैMy.2016.Summer.Vacation.png
डेविड कॉनरैड

@DavidConrad मेरी खराब: / मैंने सही किया हैcut -f 2-
टॉम सॉलिड

अब यह उस फ़ाइल के साथ काम करता है, लेकिन अभी तक एक फ़ाइल के साथ नहीं है .pngऔर इसके बाद एक नई ls
पंक्ति

2

अगर मुझे पता होता कि निर्देशिका में केवल एक एक्सटेंशन के रूप में .png के साथ फाइल होती है, तो मैं बस चलता: ls | awk -F. '{print $1}'

यह किसी भी चीज़ के लिए पहला "फ़ील्ड" लौटाएगा जहाँ फ़ाइलनाम है।

उदाहरण:

[rsingh@rule51 TESTDIR]$ ls
10.png  1.png  2.png  3.png  4.png  5.png  6.png  7.png  8.png  9.png

[rsingh@rule51 TESTDIR]$ ls | awk -F. '{print $1}'
10
1
2
3
4
5
6
7
8
9

दुर्भाग्य से यह सब पर असफल हो जायेगी फ़ाइल नाम एक से अधिक के साथ ., के रूप में Image.1.pngऔर यहां तक कि के साथ लोगों पर नहीं अच्छा नाम के अंदर विशेष वर्ण के साथ,। के रूप में आप (इनपुट) रिकॉर्ड विभाजक में awk, के रूप में उपयोग करेंगे कि newline या एक के रूप में RS। यह lsआउटपुट को पार्स करने से बचने का सुझाव दिया जाता है क्योंकि यह समस्या को छिपाने के लिए प्यार करता है जो तब उत्पन्न होगा जब आप उम्मीद नहीं करेंगे। आप उन संदर्भ 1 या 2 में अधिक पढ़ सकते हैं । BTW अच्छा विचार awk का उपयोग करने के लिए ... मैंने कुछ उदाहरण एक उत्तर में दिए।
हस्तूर

हालांकि, कोलिन द्वारा प्रदान किए गए नमूने को देखते हुए, यह ठीक काम करेगा। आपके द्वारा सुझाए गए मामले के लिए इसे काम करने के लिए, मैं शायद इसे बदल दूंगा: [rsingh @ rule51 TESTDIR] $ ls | sed -e 's / .png $ //' 10 1 2 3 4 5 6 7 8 9 harry.the.bunny whats.a.png.filename मुश्किल होने की कोशिश नहीं, लेकिन कॉलिन की जरूरत को देखते हुए, मुझे यकीन है कि क्या मुद्दा पार्सिंग ls होगा।
रायसिंह

क्षमा करें ... मुझे सिर्फ एहसास हुआ कि मैंने 'ls' [rsingh @ rule51 TESTDIR] $ ls 10.png 2.png 4.png 6.png 6.png 8.png का आउटपुट संशोधित करने से पहले फ़ाइलों के साथ निर्देशिका नहीं दिखाई थी। harry.the.bunny.png 1.png 3.png 5.png 7.png 9.png whats.a.png.filename.png [rsingh @ rule51 TESTDIR] $ ls | sed -e's / .png $ // '10 1 2 3 4 5 6 7 8 9 harry.the.bunny whats.a.png.filename
rsingh

Note1 आप से बचने के लिए की जरूरत .में \.अंदर sed -e 's/\.png$//'है, लेकिन तो यह हो जाता है एक जवाब सिर्फ लिखा। :-( note2 आप awkकुछ के साथ उपयोग करने की कोशिश कर सकते हैं ls | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}'... लेकिन आप हमेशा समस्या है कि awk पता नहीं कर सकते हैं कि क्या लाइन आ रही है या फ़ाइल नाम के अंदर एक नई पंक्ति नहीं है। मैंने अपने उत्तर में बेहतर कहने की कोशिश की। ।
हस्तूर

धन्यवाद हस्तूर, मुझे वह याद आया :)। इसके अलावा, मैंने इस मामले में सेड के पक्ष में जाग के उपयोग को खो दिया।
रायसिंह

2

आपकी टिप्पणी के अनुसार "मेरे पास एक टेक्स्ट फ़ाइल है जहां सभी नाम एक्सटेंशन के बिना सूचीबद्ध हैं। मैं एक PHP स्क्रिप्ट बनाना चाहता हूं जो पाठ फ़ाइल की तुलना फ़ोल्डर के साथ करता है यह देखने के लिए कि कौन सी फ़ाइल गायब है":

for file in $(cat yourlist) ; do
  [ -f "${file}.png" ] || {
    echo "$file : listed in yourlist, but missing in the directory"
  }
done
#assumes that filenames have no space...
# otherwise use instead:
#  while IFS= read file ; do ...(same inner loop as above)... ; done < yourlist

और रिवर्स:

for file in *.png ; do
  grep "^${file%.png}$" yourlist >/dev/null || {
    echo "$file: present in the directory but not listed in yourlist"
  }
done
#I assume there are no spaces/tabs/? before/after names in 'yourlist'. Change the script accordingly if there are some (or sanitize the list)

1

ls -l | sed 's/\.png$//'

@Roaima द्वारा हाइलाइट किया गया सबसे सटीक तरीका है। बची हुई \.pngफ़ाइलों के बिना नाम के a_png.pngरूप में सूचीबद्ध किया जाएगा:a_ :।


का उपयोग करते हुए ls -l, जैसा कि आप करते हैं, फ़ाइल विवरण देता है, यही वह नहीं है जो ओपी ने पूछा है।
एंथन

1

एक साधारण शेल लाइन (ksh, bash या zsh; डैश नहीं):

set -- *.png; printf '%s\n' "${@%.png}"

एक साधारण कार्य (नो एक्सटेंशन से):

ne(){ set -- *.png; printf '%s\n' "${@%.png}"; }

या एक फ़ंक्शन जो किसी भी एक्सटेंशन को हटा देता है (डिफ़ॉल्ट रूप से png):

ne(){ ext=${1:-png}; set -- *."$ext"; printf '%s\n' "${@%.${ext}}"; }

इस रूप में उपयोग करें:

ne jpg

यदि आउटपुट एक तारांकन चिह्न है *, तो उस एक्सटेंशन वाली कोई फ़ाइल मौजूद नहीं है।


1

आप निम्न फ़ीड की कोशिश कर सकते हैं ls का उत्पादन आपके सुपरेटर का "है।" और चूंकि आपकी सभी फाइलें name.png होंगी, आप पहले कॉलम को प्रिंट करते हैं:
ls | awk -F"." '{print $1}'


-1

अगर आपके पास sed है, तो यह बेहतर है क्योंकि यह अंतिम फ़ाइल एक्सटेंशन को हटा देगा, चाहे वह कोई भी हो (png, jpg, tiff, आदि ...)

ls | sed -e 's/\..*$//'

7
जैसे फ़ाइल नाम के लिए तोड़ता है this.is.a.dotty.txts/\.[^.]*$//इसके बजाय कोशिश करें ।
रोइमा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.