รูปแบบเปลี่ยนชื่อไฟล์แบทช์ใน terminal


48

ฉันต้องเปลี่ยนชื่อต่อไปนี้:

file_001_loremipsum.png
file_002_dolor.png
file_003_sit.png
file_004_amet.png
file_105_randomness.png

เข้าไป

upl_loremipsum.png
upl_dolor.png
upl_sit.png
upl_amet.png
upl_randomness.png

ฉันจะทำให้มันเกิดขึ้นได้อย่างไรด้วยคำสั่งเทอร์มินัลบรรทัดเดียวอย่างง่าย


1
งูหลามที่ใช้ระบบ regex รุ่นที่ไม่ปลอดภัยซึ่งทำงานซ้ำในโฟลเดอร์ย่อยทั้งหมด: stackoverflow.com/a/39698169/191246
ccpizza

คำตอบ:


79

วิธีการแก้ปัญหาตัวอย่างข้างต้นโดยใช้การเปลี่ยนชื่อ :

rename -v -n 's/file_\d{1,3}/upl/' file_*.png

การใช้งาน:

rename [options] [Perl regex search/replace expression] [files]

จากman rename:

   -v, --verbose
           Verbose: print names of files successfully renamed.
   -n, --no-act
           No Action: show what files would have been renamed.

เปลี่ยนชื่อ MAY ใช้ regex เป็นอาร์กิวเมนต์

'สิ่งที่เรากำลังมองหาที่เนื้อหาระหว่างคำพูดเดียว คุณสามารถวาง regex /แยกจากกันโดย

สูตร: s/(1)/(2)/โดยที่(1)= รูปแบบการค้นหาและ(2)= แทนที่รูปแบบ

ดังนั้นทำความคุ้นเคยกับ regexและสนุกกับการเปลี่ยนชื่อไฟล์แบตช์ตามรูปแบบ!


14
ฉันรู้ว่านี้คือ Ubuntu แต่ถ้าใครจบลงที่นี่ถึงแม้ว่าพวกเขากำลังมองหาวิธีการแก้ปัญหา OS X (ฉันไม่) มีการติดตั้งได้อย่างง่ายดายด้วยrename brew install rename
sandstrom

ใน Ubuntu 18.10 ให้ทำการ--no-actตั้งค่าสถานะ--nonoแทน คำตอบนี้อาจมีความชัดเจนมากขึ้น: [files]หมายถึงไฟล์ที่จับคู่รูปแบบเริ่มต้นในไดเรกทอรีปัจจุบันที่ต้องการเปลี่ยนชื่อ (เช่น*จับคู่ทุกอย่าง แต่เฉพาะในไดเรกทอรีปัจจุบัน)
Patrick Dark

ลิงก์ของคุณชี้ไปยังอีกrenameรูปแบบหนึ่งซึ่งมีรูปแบบrename from to fileและไม่รองรับนิพจน์ทั่วไป ที่จริงแล้วการกระจาย Linux ของฉัน (Cent OS 7) มีรุ่นนั้นอย่างแน่นอน
Alex Che

6

หากไฟล์อยู่ในไดเร็กทอรี severals ให้เปลี่ยนชื่อหลังจาก find like:

find -iname file_*.png -type f -exec rename -n 's/file_[0-9]{3}(.*\.png)/upl$1/' {} \;

-n หลังจากเปลี่ยนชื่อคือการทดสอบลบออกเพื่อดำเนินการต่อ! -)

เช่นนี้คุณเชื่อมโยงค้นหาและเปลี่ยนชื่อพลังงาน

ส่วนตัวผมใช้มันเพื่อเปลี่ยนชื่อส่วนหัวของแหล่งที่มา. h เป็น. hpp

find -iname *.h -type f -exec rename 's/(.*\.)h/$1hpp/' {} \;

มีเอกสารสำหรับ-iname, -typeและ-execธงที่manpages.ubuntu.com/manpages/bionic/man1/find.1.html#expression ( find --helpไม่เป็นประโยชน์สำหรับคำสั่งนี้โดยเฉพาะ) TL; DR: -inameจับคู่ตัวพิมพ์กับรูปแบบ -type fตรงกับ“ ไฟล์ปกติ”; และ-execเรียกใช้งานนิพจน์จนกว่าจะพบ;อักขระ (เซมิโคลอน)
Patrick Dark

5

สิ่งนี้สามารถทำได้ด้วยเวทมนตร์เพียงเล็กน้อยของการขยายพารามิเตอร์ bash

for f in file_[0-9]*_*; do mv $f upl_${f#file_[0-9]*_}; done

file_[0-9]*_*;- รูปแบบแรกถูกใช้เพื่อไปยังไฟล์ทั้งหมดที่ขึ้นต้นด้วย 'file_anynumber_'
${f#file_[0-9]*_}- รูปแบบที่สองfile_[0-9]*_ใช้ในการขยายพารามิเตอร์ซึ่งบอกว่าทุบตีเพื่อลบ 'file_anynumber_' จากการขอร้องของสตริง

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับParameter expansion:

man bash

โปรดทราบว่าสิ่งนี้ใช้ globs ไม่ใช่ regex ดังนั้น[0-9]*จะจับคู่หนึ่งหลักตามด้วยสตริงใด ๆ อาจเป็นวิธีที่ดีกว่าในการจับคู่ตัวเลขเพียงอย่างเดียว แต่ฉันไม่สามารถคิดรวบรัดได้
wjandrea

คุณจะสามารถแนะนำวิธีให้คำสั่งนี้ทำงานซ้ำในไดเรกทอรีย่อยทั้งหมดได้หรือไม่?
ฟรานเชสโก DM
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.