إعادة تسمية سلسلة من الملفات
سؤال
محاولة إعادة تسمية سلسلة من الملفات على خادم Linux. من السهل العثور على الملفات التي أريدها:
find . -type f -wholename \*.mbox
بالطبع ، كونه ملفات Mbox ، فإن بعضها لديه مسافات في الأسماء ، لذلك يصبح:
find . -type f -wholename \*.mbox -print0
سأقوم بالأنابيب إلى XARGS حتى أتمكن من إعادة تسمية الملفات:
find . -type f -wholename \*.mbox -print0 | xargs -0 -I{} echo ${"{}"/.mbox/}
يجب أن يعيد Echo شيئًا مثل البريد الوارد ، وربط box.mbox ، ومع ذلك ، يشكو باش:
bash: ${"{}"/.mbox/}: bad substitution
كيف يمكنني اصلاح هذا؟ أود أن أحاول الاحتفاظ به في حل Find/Xargs إن أمكن ، حتى لا أضيف الكثير من بنيات الحلقات حوله.
المحلول
محاولة
find . -type f -wholename \*.mbox | sed 's/\(.*\)\.mbox/mv "\1.mbox" "\1"/' | sh
هذا ليس دليلًا على حذبة 100 ٪ إذا كان بعض الملفات يحتوي على أحرف اقتباس مزدوجة ، لكنني أفترض أنه يمكنك تجاهل ذلك :)
نصائح أخرى
GNU موازية http://www.gnu.org/software/paralled/ لديه {.} الذي يزيل الامتداد:
find . -type f -wholename \*.mbox -print0 | parallel -0 mv {} {.}
إذا كنت تعرف أن أسماء الملفات لا تحتوي على n ، فسيعمل هذا أيضًا:
find . -type f -wholename \*.mbox | parallel mv {} {.}
أعتقد أنك بحاجة إلى هذا:
find . -wholename \*.mbox | awk '{new=$0; gsub("\.mbox$", "", new) ; system("mv \"" $0 "\" \"" new "\"") }'
(يجب أن تكون متوافقة مع Gawk و Mawk ، تم اختبارها على Mawk). لا يستخدم XARGS ، ولكن لاحظ أنه لا يتخلى عن عملية جديدة لكل ملف تم نقله. إذا كنت بحاجة إلى نقل كمية كبيرة من الملفات ، فستلاحظ الميزة. المحاربين: إذا كان أي من الملفات سيحتوي على سطر جديد باسمه ، فسوف تواجه مشكلة (ولكن إذا كانت هذه مشكلة ، فسيكون الله معك).
يمكنك تحسين هذا الحل باستخدام XARGS لحذف ملفات متعددة على واحد rm
استدعاء.
إذا كنت بحاجة حقًا إلى السرعة ، أقترح أن تستخدم نصًا بيثون بدلاً من AWK. الذي سيفعل كل rm
دون شوكة واحدة.
هل يمكنك استخدام إعادة تسمية (1)؟ يأتي مع بيرل.
يمكنك المحاولة:
find . -type f -wholename \*.mbox -print0 | sed 's/\.mbox//'
مشكلتك هي في محاولة للتجول في xargs. في تلك المرحلة "{}"
لا يعني أي شيء.
لإعادة تسمية الملفات (على افتراض أنك تحت باش)
find . -type f -wholename \*.mbox -print0 | \
while read I ; do
mv $I $(echo $I | sed 's/\.mbox//') ;
done ;
هنا تذهب ، هذا يجب أن يفعل الخدعة ....
# find .
.
./test.tst
./test1.tst
./test2.tst
./test/test4.tst
./test/test5.tst
#
for file in `find . -type f`
do
mv $file ${file%.tst}.new
done
# find .
.
./test
./test/test4.new
./test/test5.new
./test1.new
./test2.new