मेरे पास 20 फाइलों की एक सूची है, उनमें से 10 में पहले से ही 1970-01-01- नाम की शुरुआत में है और 10 में नहीं है (शेष सभी एक छोटे अक्षर से शुरू होते हैं)।

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

काम करता है

find ./ -regex './[a-z].*' | xargs -I {}  basename {} | xargs -I {} mv {} 1970-01-01-{}

इसलिए केवल एक xargs या -exec के साथ समाधान ढूंढ रहे हैं?

1
infoclogged 3 जिंदा 2018, 17:53

2 जवाब

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

आप केवल एक rename कमांड का उपयोग कर सकते हैं:

rename -n 's/^([a-z])/1970-01-01-$1/' *

मान लें कि आप वर्तमान निर्देशिका में मौजूद सभी फाइलों पर काम कर रहे हैं।

ध्यान दें कि -n ध्वज (ड्राई रन) केवल rename कमांड द्वारा इच्छित कार्य दिखाएगा, लेकिन वास्तव में किसी भी फाइल का नाम नहीं बदलेगा।

यदि आप find के साथ संयोजन करना चाहते हैं तो इसका उपयोग करें:

find . -type f -maxdepth 1 -name '[a-z]*.txt' -execdir rename -n 's/^/1970-01-01-/' {} +
2
anubhava 3 जिंदा 2018, 18:18

मैं हमेशा शॉर्ट कोड पर पठनीय कोड पसंद करता हूं।

r() {
  base=$(basename "$1")
  dir=$(dirname "$1")
  if [[ "$base" =~ ^1970-01-01- ]]
  then
    : "ignore, already has correct prefix"
  else
    echo mv "$1" "$dir/1970-01-01-$base"
  fi
}
export -f r

find . -type f -exec bash -c 'r {}' \;

यह सिर्फ यह भी प्रिंट करता है कि क्या किया गया होगा (परीक्षण के लिए)। वास्तविक चीज़ के लिए mv से पहले echo को हटा दें।

ध्यान रखें कि mv मौजूदा फाइलों को अधिलेखित कर देगा (यदि कोई ./a/b/c और एक ./a/b/1970-01-01-c पहले से है)। इससे बचने के लिए विकल्प -i से mv का उपयोग करें।

0
Alfe 3 जिंदा 2018, 18:13