วิธีเปลี่ยนชื่อไฟล์เป็นชุดใน macOS Terminal


123

ฉันมีโฟลเดอร์ที่มีชุดไฟล์ชื่อ:

prefix_1234_567.png
prefix_abcd_efg.png

ฉันต้องการแบทช์ลบขีดล่างและเนื้อหาตรงกลางออกหนึ่งรายการดังนั้นผลลัพธ์จะเป็น:

prefix_567.png
prefix_efg.png

เกี่ยวข้อง แต่ไม่สามารถอธิบายได้อย่างสมบูรณ์:


ดูช่วงและวิธีการสตริงย่อยของ NSString และ NSMutableString
Grady Player

1
คุณได้พิจารณาโซลูชันที่ไม่ใช่เทอร์มินัลสำหรับสิ่งนี้หรือไม่? เวิร์กโฟลว์ Automator สามารถดำเนินการประเภทนี้ได้อย่างง่ายดาย คุณสามารถสร้างเวิร์กโฟลว์อัตโนมัติเพื่อเปลี่ยนชื่อไฟล์ทั้งหมดและแทนที่ข้อความ_*_ด้วยช่องว่าง
เข้ารหัส

ฉันคิดว่า Automator ไม่สามารถทำสัญลักษณ์แทนได้
ลักพาตัว

คำตอบ:


234

ในกรณีเฉพาะของคุณคุณสามารถใช้bashคำสั่งต่อไปนี้( bashคือเชลล์เริ่มต้นบน macOS):

for f in *.png; do echo mv "$f" "${f/_*_/_}"; done

หมายเหตุ: หากมีโอกาสที่ชื่อไฟล์ของคุณจะขึ้นต้นด้วย-ให้วางไว้ข้าง-- หน้า [1]:
mv -- "$f" "${f/_*_/_}"

หมายเหตุ: echoอยู่ข้างหน้าmvเพื่อดำเนินการแบบแห้ง ลบออกเพื่อทำการเปลี่ยนชื่อจริง

คุณสามารถเรียกใช้จากบรรทัดคำสั่งหรือใช้ในสคริปต์

  • "${f/_*_/_}"เป็นแอปพลิเคชันของbash การขยายพารามิเตอร์ : รูปแบบการจับคู่สตริงย่อย (แรก) _*_ถูกแทนที่ด้วยลิเทอรั_ลตัดโทเค็นกลางออกจากชื่อได้อย่างมีประสิทธิภาพ
  • โปรดสังเกตว่า_*_เป็นรูปแบบ (นิพจน์ตัวแทนเช่นเดียวกับที่ใช้สำหรับ globbing) ไม่ใช่นิพจน์ทั่วไป (เพื่อเรียนรู้เกี่ยวกับรูปแบบเรียกใช้man bashและค้นหาPattern Matching)

หากคุณพบว่าตัวเองไฟล์ชุดเปลี่ยนชื่อบ่อยพิจารณาติดตั้งเครื่องมือพิเศษเช่น Perl-basedrenameยูทิลิตี้ บน macOS คุณสามารถติดตั้งได้โดยใช้Homebrewตัวจัดการแพ็คเกจยอดนิยมดังต่อไปนี้:

brew install rename

นี่คือคำสั่งที่เทียบเท่ากับด้านบนโดยใช้rename:

rename -n -e 's/_.*_/_/'  *.png

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

  • คล้ายกับbashวิธีการแก้ปัญหาs/.../.../เปลี่ยนตัวข้อความดำเนินการ แต่ - แตกต่างจากในbash- จริงการแสดงออกปกติจะใช้

[1] วัตถุประสงค์ของการโต้แย้งพิเศษ--ซึ่งได้รับการสนับสนุนโดยสาธารณูปโภคมากที่สุดคือการส่งสัญญาณว่าข้อโต้แย้งที่ตามมาควรจะถือว่าเป็นตัวถูกดำเนินการ (ค่า) ถึงแม้ว่าพวกเขามีลักษณะเหมือนตัวเลือกเนื่องจากการเริ่มต้นด้วยการ-เป็นจาค็อบซีบันทึก


3
คำตอบที่ดีทำงานได้อย่างสมบูรณ์ ฉันขอขอบคุณที่คุณกลับไปแก้ไขเพื่ออธิบายเพิ่มเติมและให้วิธีแก้ปัญหาที่สวยงามยิ่งขึ้นหากฉันทำซ้ำ อีกครั้งขอบคุณมากมีประโยชน์มาก
kidnim

4
ตัวอย่างการใช้การแทนที่ที่ตรงกัน ( .*-> $1) เช่นเปลี่ยนชื่อFoo bar S01E01 biz baz.extเป็นS01E01.ext:rename -n -e 's/.*(S[0-9]{2}E[0-9]{2}).*(\.[a-z]{2,4})/$1$2/' *
Steve Robbins

2
ชอบความคิดในการใช้echoสำหรับการวิ่งแบบแห้ง ขอบคุณสำหรับทิป!
James Wright

ขอแนะนำให้ทำbrew install rename
Chris Redford

98

ในการเปลี่ยนชื่อไฟล์คุณสามารถใช้renameยูทิลิตี้:

brew install rename

ตัวอย่างเช่นในการเปลี่ยนสตริงการค้นหาในชื่อไฟล์ทั้งหมดในไดเร็กทอรีปัจจุบัน:

rename -nvs searchword replaceword *

ลบพารามิเตอร์ 'n' เพื่อใช้การเปลี่ยนแปลง

ข้อมูลเพิ่มเติม: man rename


1
OS Xเวอร์ชันของGNU bash( x86_64-apple-darwin ) ไม่รวมยูทิลิตี้การเปลี่ยนชื่อ
l'L'l

4
ขอบคุณใช่ต้องติดตั้งผ่านbrew install rename
David Thomas

2
เคล็ดลับนี้เจ๋งมาก! ฉันพิมพ์rename -vs GLYCOPHORIN GLYCC *และตอนนี้มันเปลี่ยนชื่อไฟล์ 450+ โดยอัตโนมัติ และเร็วสุด ๆ ด้วย.
Sander W. van der Laan

3
ยอดเยี่ยม ชอบส่วน "แสดงสิ่งที่จะเปลี่ยนแปลง" ก่อนที่มันจะเปลี่ยนชื่อสิ่งต่างๆ!
Ben Duffin

3
คุณสามารถใช้นิพจน์ทั่วไปได้เช่นกัน เปลี่ยนชื่อ / 123 / onetwothree / g '*
ไบรอัน

12

คุณสามารถใช้ sed:

ls * | sed -e 'p;s@_.*_@_@g' | xargs -n2 mv

ผลลัพธ์:

prefix_567.png prefix_efg.png

* ในการทำ dry-run ก่อนให้แทนที่mvในตอนท้ายด้วยecho

คำอธิบาย:

  • e: เป็นทางเลือกสำหรับ 1 คำสั่ง sed
  • p: เพื่อพิมพ์อินพุตเป็น sed ในกรณีนี้จะเป็นชื่อไฟล์ดั้งเดิมก่อนการเปลี่ยนชื่อใด ๆ
  • @: เป็นการแทนที่ / ตัวอักษรเพื่อให้อ่านง่ายขึ้น นั่นคือแทนที่จะใช้ sed s / search / replace / g ให้ใช้ s @ search @ replace @ g
  • _. *: ขีดล่างเป็นอักขระหลีกเพื่ออ้างถึง "." ที่แท้จริง อักขระศูนย์ครั้งหรือมากกว่า (ตรงข้ามกับอักขระใด ๆ ใน regex)
  • -n2: ระบุว่ามี 2 เอาต์พุตที่ต้องส่งต่อไปยัง mv เป็นพารามิเตอร์ สำหรับแต่ละอินพุตจากlsคำสั่ง sed นี้จะสร้างเอาต์พุต 2 เอาต์พุตซึ่งจะถูกส่งไปยัง mv

1
ฉลาดถ้าวิธีแก้ปัญหาค่อนข้างลึกลับ การทำให้สิ่งนี้กว้างขึ้นเพื่อรองรับชื่อไฟล์ที่มีช่องว่างฝังตัวจะได้รับความลับมากยิ่งขึ้น: ls * | xargs -I % bash -c 'echo mv "%" "$(sed 's@_.*_@_@' <<<"%")"'(ลบechoเพื่อเปลี่ยนชื่อจริง)
mklement0

2
ความลับ? ฉันรักสิ่งนี้!
Bilal Akil

7

ฉันมีชุดไฟล์ที่มีลักษณะเช่นนี้: be90-01.png และจำเป็นต้องเปลี่ยนเส้นประเป็นขีดล่าง ฉันใช้สิ่งนี้ซึ่งได้ผลดี:

for f in *; do mv "$f" "`echo $f | tr '-' '_'`"; done


1

การใช้ mmv

mmv '*_*_*' '#1_#3' *.png

sudo apt-get install mmvคุณต้องติดตั้งครั้งแรก
αғsнιη

1
ให้นี้เป็น OS X, brew install mmvขั้นตอนการติดตั้งที่ถูกต้องคือ
buckaroo1177125

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