फ़ाइनल कमांड का उपयोग करके फ़ाइल नाम से (1) कैसे निकालें


13

मैंने हाल ही में अपनी सभी FLAC फ़ाइलों को 44.1 kHz की कम नमूना दर और 24 बिट्स की बिट गहराई (क्योंकि iPhone / iPod ऊपर कुछ भी समर्थन नहीं करता है) को अपने मैक ओएस 10.7 (शेर) पर XLD का उपयोग करके परिवर्तित किया है।

हालाँकि मैंने XLD को पिछली सभी फ़ाइलों को ओवरराइड करने के लिए कहा था, लेकिन XLD (1)ने बहुत से फ़ाइल की तरह अंत में जोड़ा

some_song.m4a

सेवा

some_song(1).m4a

इसलिए अब मैं (1)उन सभी FLAC फ़ाइलों को हटाना चाहता हूं जिन्हें मैंने कनवर्ट किया था।

मुझे पता है कि मैं शायद फ़ाइलों का नाम बदलने के लिए कुछ प्रोग्राम या यहां तक ​​कि एक AppleScript का उपयोग कर सकता था, लेकिन मैं कमांड लाइन के पुराने स्कूल के तरीके का उपयोग करके सीखना चाहता था।

मुझे पता है कि find . -name *\(1\).m4aसभी परिवर्तित FLAC फ़ाइल हड़प लेंगे।

आगे मुझे पता है कि मुझे कुछ करना है -execऔर mvसभी मिली फ़ाइलों का नाम बदलना है। लेकिन जो मैं समझ नहीं पा रहा हूं वह यह है कि मूल फ़ाइल नाम को कैसे रखा जाए और केवल इसे हटा दिया जाए (1)

हो सकता है कि मुझे उस फ़ाइलनाम के भाग को संग्रहीत करने के लिए कुछ समूह regex कैप्चरिंग करने की आवश्यकता हो जिसे मैं संशोधित नहीं करना चाहता? या हो सकता है कि यह सब कुछ एक पंक्ति में करना संभव न हो और मुझे एक शेल स्क्रिप्ट बनानी चाहिए (जो कि मैं ऐसा करने में सहज नहीं हूं, लेकिन मैं इसे आजमाने को तैयार हूं)।

किसी भी सुझाव या सुझाव का स्वागत किया है! धन्यवाद!


5
क्यों होता है पतन? यह एक वैध प्रश्न की तरह लगता है ...

आपके विशेष प्रश्न (पर find) से असंबंधित लेकिन आपकी वास्तविक समस्या को हल करना (ऑडियो फ़ाइलों को परिवर्तित करना), आपको audiotools.sourceforge.net पर और इस उदाहरण मामले ( macosx
meduz

जवाबों:


13

findअंतिम उपाय के रूप में आउटपुट को पार्स करने का प्रयास न करें । यह महसूस करना महत्वपूर्ण है कि यूनिक्स फ़ाइल सिस्टम पर, फ़ाइल नाम तार नहीं हैं (एक आम गलतफहमी), लेकिन बाइनरी बूँदें जो किसी भी वर्ण को छोड़कर /और अशक्त चरित्र को शामिल कर सकती हैं । सुरक्षित रूप से और सही ढंग से फ़ाइल नामों को पार्स करना एक दर्द के लिए पर्याप्त है जो उस समय का 99% है जो आप इसे पूरी तरह से करने से बचना चाहते हैं (बस यह देखें कि @ yarek के उत्तरsed में बालों की अभिव्यक्ति कितनी आकर्षक है और यहां तक ​​कि सभी मामलों को कवर नहीं करता है) । शुक्र है, इस मामले में बहुत सरल दृष्टिकोण है:

find . -name '*(1).m4a' -execdir sh -c \
'for arg; do mv "$arg" "${arg%(1).m4a}".m4a; done' _ {} \+

साफ दृष्टिकोण के रूप में अभी तक बालों के रूप में बालों वाला रुख :) +1
yrk

1
यहाँ कुछ याद आ रहा है ... कहाँ है done?
yrk

@yarek पकड़ने के लिए धन्यवाद। इस और sedपाइप के दृष्टिकोण के बीच सबसे बड़ा अंतर यह है कि यह अधिक सुरक्षित है। रेगेक्स बैकस्लैश सूप की तुलना में पढ़ना अभी भी आसान है, बशर्ते आप कुछ बुनियादी शेल स्क्रिप्टिंग कंस्ट्रक्शन को समझें।
jw013

आप सही हे; यह बहुत साफ है। और $argचर को पढ़ने में बहुत आसान बनाता है।
hobbes3

1
@DQdlM झलकी मैं ऊपर पोस्ट बस है findलागू shकाफी पोर्टेबल POSIX वाक्य रचना के साथ। अधिक जानकारी के लिए, आप पैरामीटर विस्तार पर अनुभाग की जांच कर सकते हैं , यौगिक आदेशों पर अनुभाग जो forलूप , और पोसिक्स findकल्पना की व्याख्या करता है । उन संसाधनों के अलावा, मुझे आपके किसी भी विशिष्ट प्रश्न का उत्तर देने में खुशी होगी ।
jw013

6

डेबियन और उबंटू पर, मैं rename 's/\(1\)//' *.m4aआपकी समस्या को हल करने के लिए उपयोग कर सकता हूं ।


अजीब, मैं कर सकता हूं man rename, लेकिन मेरे पास वास्तव में नहीं है rename: -bash: rename: command not found( which renameकुछ भी नहीं दिखाता है)।
hobbes3

@ hobbes3 पर मैक यहाँ man -a renameपाता है नाम बदलने syscall, और - (2) का नाम बदलें (n) - TCL आदेश। वहां न तो नाम बदला है (1) और न ही उपयोगिता।
yrk

1
IIRC, renameएक पर्ल स्क्रिप्ट है जिसमें कुछ पर्ल इंस्टॉल में शामिल उदाहरणों के साथ शामिल किया गया है, और एक जोड़े के डिस्ट्रोस इसे रास्ते में शामिल करते हैं क्योंकि यह एक सुविधाजनक कमांड है। (@ होब्स शायद आप इसे इंटरनेट पर पा सकते हैं)
केविन

मेरे सिस्टम पर @ केविन renameसामान्य बाइनरी है (पर्ल नहीं)। हालांकि एक और चेतावनी यह है कि renameसमर्थन के सभी संस्करण regexes नहीं हैं। उदाहरण के लिए मेरे पास संस्करण केवल आपको सीधे स्ट्रिंग प्रतिस्थापन करने की अनुमति देता है, जैसेrename '(1)' '' *.m4a
पैट्रिक

1
पर्ल renameस्क्रिप्ट केवल डेबियन और डेरिवेटिव द्वारा स्थापित की गई है। अन्य लिनक्स सिस्टम में एक अलग renameउपयोगिता है (पैट्रिक द्वारा दिखाया गया है)। OSX में न तो है।
गाइल्स का SO- बुराई पर रोक

4

Zsh में, का उपयोग कर ZMV :

autoload zmv      # you can put this line in your .zshrc
zmv '(*)\(1\)(*)' '$1$2'

दूसरे तर्क में (नया नाम), $1और स्रोत पैटर्न में $2कोष्ठक समूहों को देखें (PATTERN)। इस नाम बदलने का एक और तरीका है

zmv '(*)' '${1/\(1\)/}'

3

निम्नलिखित दृष्टिकोण आपको उन्हें निष्पादित करने से पहले उत्पन्न आदेशों का पूर्वावलोकन / पूर्वावलोकन करने की क्षमता देता है, और यह बहुत पोर्टेबल है: यह न केवल मैक पर काम करना चाहिए, न केवल बैश के साथ, और न केवल जीएनयू सेड के साथ; सिस्टम पर भी (1) बिना किसी परेशानी के findइसे du(1) के साथ स्थानापन्न करना संभव है ।

find . -name '*(1).m4a' |
sed 's/\(.*\)(1).m4a$/mv & \1.m4a/' 

यदि मुद्रित आदेशों से खुश हैं, तो | sh -xसंलग्न के साथ फिर से चलाएं ।

यदि फ़ाइल नामों में रिक्त स्थान के बारे में चिंतित हैं, तो सभी रिक्त स्थान से बचने के लिए एक और एस जोड़ें :

find . -name '*(1).m4a' |
sed -e 's/ /\\ /g' -e 's/\(.*\)(1).m4a$/mv & \1.m4a/'

यदि अन्य विशेष वर्णों की अपेक्षा की जाती है, तो यह एक लिट्ल बिट अधिक मुश्किल हो जाता है:

find . -name '*(1).m4a' |
sed -e "s/'/'\\\\''/g" -e 's/\(.*\)(1).m4a$/mv '\''&'\'' '\''\1.m4a'\'/

पहला कार्य सभी 'को एक ऐसे रूप में परिवर्तित कर देता है कि जब-के '...'-स्ट्रिंग के बीच में ये सचमुच में ले जाते हैं । दूसरा फ़ंक्शन एमवी कमांड उत्पन्न करता है जिनके तर्क भीतर संलग्न हैं '...'


1
वह आदेश फ़ाइल नाम (रिक्त स्थान (, और अन्य सभी विशेष वर्ण) से बच नहीं रहा है या फ़ाइल नाम के आसपास उद्धरण जोड़ रहा है। मैंने आपकी आज्ञा को संशोधित करने की कोशिश की, लेकिन मैं यह नहीं पता लगा सका कि mvकमांड के लिए दोनों फ़ाइलनामों के आसपास कैसे उद्धरण जोड़ें । आपके आदेश से परिणामी आउटपुट में से एक है mv ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us(1).m4a ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us.m4a। और अगर मुझे वह कमांड मिलती है तो मुझे मिलेगा -bash: syntax error near unexpected token '('
hobbes3

यह एक होमवर्क माना जाता है :) लेकिन ठीक है, मैं जवाब अपडेट
करूंगा

वैसे GNU sed eप्रतिस्थापन के बाद कमांड जोड़कर खुद ही कमांड निष्पादित कर सकता है । उदाहरण के लिए find . -name '*(1).m4a' | sed 's/\(.*\)(1).m4a$/mv & \1.m4a/e'पाइपिंग के बिना कमांड को हटा देगा sh -x
भीड़

@Rush ही एकमात्र ऐसा sed है जो ऐसा करता है; और इसे वैसे भी
खोलना

2
मुझे नहीं लगता कि हमें नीच होना चाहिए। यह सब के बाद एक वैध समाधान है।
hobbes3

1

यहाँ एक छोटी स्क्रिप्ट है जो इसे करती है:

for var in `find . -type f -name "*(1).m4a"`; do
    new=`echo $var | cut -d'(' -f1`;
    mv $var $new.m4a;
done

यह उनके नाम पर रिक्त स्थान वाली फाइलों पर चोक करेगा; यह भी के लिए बड़े पर्याप्त अस्थायी भंडारण की आवश्यकता है`find ...`
yrk
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.