मेरे पास फ़ाइल नामों की एक सूची है जिसमें डबल डैश हैं:

New York--1984 and counting.txt
Timeless Wonders--Silver-Guardians.txt
Project Blue Gale--Hills of Green.txt

मुझे डबल डैश से पहले डबल डैश और सभी वर्णों को हटाने की आवश्यकता है:

1984 and counting.txt
Silver-Guardians.txt
Hills of Green.txt

यहाँ SED का उपयोग करते हुए मोड कोड है:

for f in *; do mv "$f" "$(sed 's/[^\--]*--//')"; done

आरई त्रुटि: अमान्य वर्ण श्रेणी

अगर मैं इसे बदलता हूं, तो यह केवल एक डैश की खोज करता है, यह काम करता है। तो मैं डबल डैश की खोज कैसे कर सकता हूं? अग्रिम में धन्यवाद।

sed
1
big_smile 23 जिंदा 2020, 15:25
1
शायद "$(sed 's/^[^-]*--//' <<< "$f")" करेंगे?
 – 
Wiktor Stribiżew
23 जिंदा 2020, 15:29
हां, यह काम करता है, मैंने जो पूरा आदेश इस्तेमाल किया वह for f in *; do mv "$f" "$(sed 's/^[^-]*--//' <<< "$f")"; done था। कृपया उत्तर के रूप में पोस्ट करें ताकि मैं सही के रूप में चिह्नित कर सकूं।
 – 
big_smile
23 जिंदा 2020, 15:31

3 जवाब

सबसे बढ़िया उत्तर

त्रुटि इस तथ्य के कारण है कि आपका [^\--] पैटर्न \ (दिसंबर 92) और - (दिसंबर 45) के बीच की सीमा को परिभाषित करता है, जो गलत है।

मैं उपयोग करने का सुझाव देता हूं

for f in *; do mv "$f" "$(sed 's/^[^-]*--//' <<< "$f")"; done

sed 's/^[^-]*--//' कमांड स्ट्रिंग की शुरुआत से -- सबस्ट्रिंग तक - के अलावा सभी 0 या अधिक वर्णों को हटा देगा।

या, आप पैरामीटर विस्तार का उपयोग कर सकते हैं, ${f#*--} (जैसा कि @tripleee द्वारा इंगित)। यह स्ट्रिंग की शुरुआत से यथासंभव कम (#*) पहले -- तक 0 या अधिक वर्णों को हटा देगा।

देखें ऑनलाइन डेमो:

s="New York--1984 and counting.txt"
echo "${s#*--}";
sed 's/^[^-]*--//' <<< "$s"

आउटपुट:

1984 and counting.txt
1984 and counting.txt
2
Wiktor Stribiżew 23 जिंदा 2020, 15:46
2
बेशक, शेल पैरामीटर विस्तार प्रदान करता है जो काफी अधिक कुशल होना चाहिए: mv "$f" "${f#*--}" (हालांकि आपको डबल डैश से पहले डैश को रोकने के लिए एक अलग गार्ड जोड़ने की आवश्यकता है यदि ऐसा कुछ है जिसे आप रोकना चाहते हैं)।
 – 
tripleee
23 जिंदा 2020, 15:38
1
हां, कल इसे मेरी लिपि में इस्तेमाल किया गया था, लेकिन मैंने यहां रेगेक्स दृष्टिकोण पर ध्यान केंद्रित किया था
 – 
Wiktor Stribiżew
23 जिंदा 2020, 15:40
1
[^-]* New-York-- को पकड़ने में विफल हो जाएगा - केवल यह मानते हुए कि हटाए जाने वाले टेक्स्ट में एक सिंगल डैश / माइनस दिखाई दे सकता है। .*? उस स्थिति को भी कवर करेगा।
 – 
virolino
23 जिंदा 2020, 15:41
1
sed आलसी क्वांटिफायर का समर्थन नहीं करता है। पैरामीटर विस्तार के यहां काम करने की अधिक संभावना है।
 – 
Wiktor Stribiżew
23 जिंदा 2020, 15:43
1
अधिकांश sed बोलियां गैर-लालची मिलान का समर्थन नहीं करती हैं। लेकिन ओपी विशेष रूप से वैसे भी डैश के साथ कुछ भी टालना चाहता है।
 – 
tripleee
23 जिंदा 2020, 15:43

यह आपके लिए काम कर सकता है (जीएनयू समानांतर):

parallel --dryrun mv {} {= s/.*?--// =} ::: *.txt

स्रोत फ़ाइलों के साथ निर्देशिका में कमांड चलाएँ और आउटपुट का निरीक्षण करें। यदि सभी चेक आउट हो जाते हैं, तो --dryrun विकल्प को हटा दें और फिर से चलाएँ।

GNU sed का उपयोग कर एक वैकल्पिक समाधान:

ls *.txt | sed -E 'h;s/--/\n/;H;g;s/(.*)\n.*\n(.*)/mv -v "\1" "\2"/e'

एन.बी. यदि आप वास्तविक रूप से चलाने से पहले जांचना चाहते हैं तो e प्रतिस्थापन ध्वज को हटा दें।

4
potong 23 जिंदा 2020, 18:39

आप इसे rename टूल से कर सकते हैं। पर्ल वन, उपयोग-लिनक्स एक नहीं):

$ rename -n 's/.*?--//' *.txt
'New York--1984 and counting.txt' would be renamed to '1984 and counting.txt'
'Project Blue Gale--Hills of Green.txt' would be renamed to 'Hills of Green.txt'
'Timeless Wonders--Silver-Guardians.txt' would be renamed to 'Silver-Guardians.txt'

-n को हटाने से वास्तव में नामकरण होता है। .*?-- एक रेगुलर एक्सप्रेशन है जो -- की पहली घटना तक सब कुछ गैर-लालची से मेल खाता है।

2
Benjamin W. 23 जिंदा 2020, 17:52