เปลี่ยนชื่อกลุ่มไฟล์ด้วยคำสั่งเดียว


38

หากฉันมีกลุ่มไฟล์ที่มีนามสกุล. htm ฉันจะเปลี่ยนชื่อพวกเขาทั้งหมดเป็น. html ได้อย่างไร

mv *.htm *.html

ไม่สำเร็จ.


เพียงเพื่อความสมบูรณ์ren *.htm *.htmlจะทำงานใน Windows
Brian Burns

คำตอบ:


50

หรือคุณสามารถใช้ทุบตีบริสุทธิ์ ... (ยกเว้น mv นั่นคือ .. )

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

และหลีกเลี่ยงสิ่งที่เป็นฐานที่น่ารังเกียจ ;)

Bash มีชุดตัวเลือกการขยายตัวแปรที่หลากหลาย อันที่ใช้ที่นี่ '%' จะลบส่วนต่อท้ายการจับคู่ที่เล็กที่สุดออกจากค่าของตัวแปร รูปแบบนั้นเป็นรูปแบบแบบกลมดังนั้น${file%.*}จะใช้งานได้เช่นกัน ตัวดำเนินการ '%%' จะลบส่วนต่อท้ายการจับคู่ที่ใหญ่ที่สุดและสามารถใช้แทนกันได้ในตัวอย่างข้างต้นเนื่องจากรูปแบบได้รับการแก้ไขแล้ว${file%%.*}.htmlจะเปลี่ยน abhtm เป็น a.html

ดูที่ส่วนย่อยตัวแปรของ manpage ทุบตีสำหรับเทคนิคประณีตมากขึ้น มีหลายสิ่งที่สามารถทำได้ภายในการทุบตีโดยตรง


1
นอกจากนี้ยังทราบว่าสิ่งเหล่านี้ขยายพารามิเตอร์ไม่ จำกัด เพียงการทุบตี พวกมันมีอยู่ในเชลล์ที่ได้มาจาก Bourne ทั้งหมด ( sh , ksh , bash , zsh , dash , ash , ฯลฯ ) การขยายเป็นส่วนหนึ่งของข้อกำหนด POSIX สำหรับ "ภาษาคำสั่งเชลล์"และสามารถพกพาได้อย่างสะดวก
Chris Johnsen

11

ไม่ควรมีช่องว่างบรรทัดใหม่หรือช่องว่างอื่นในชื่อไฟล์ แต่คำตอบของ freiheit รุ่นนี้จะจัดการกับสิ่งเหล่านั้น นอกจากนี้ยังใช้$()แทน backticks เพื่อให้อ่านได้พร้อมกับประโยชน์อื่น ๆ

for file in *.htm
do
    mv "$file" "$(basename "$file" .htm).html"
done

ดียิ่งขึ้น - สำหรับกรณีพิเศษที่เพิ่มไปยังจุดสิ้นสุด:

for file in *.htm
do
    mv "$file" "${file}l"
done

11

rename(1)เป็นสาธารณูปโภค Perl ที่ทำสิ่งที่คุณต้องการ ในกรณีนี้:

rename 's/\.htm$/.html/' *htm

หรือถ้าคุณใช้ไดเรกทอรีย่อยเช่นกัน

(ต้องทุบตี 4.0 และการตั้งค่า GLOBSTAR นี้: shopt -s globstar)

rename 's/\.htm$/.html/' **/*htm


1
การเปลี่ยนชื่อนั้นง่ายกว่า แต่ไม่ใช่โปรแกรมยูนิกซ์มาตรฐาน คำถามเดิมไม่ได้ระบุว่ายูนิกซ์ใด ดูเหมือนว่าจะเป็น "prename" ในบางสถานที่
อิสระ

2
renameมาพร้อมกับ Perl และโดยพื้นฐานแล้วยูนิกซ์ทุกตัวจะมาพร้อมกับ Perl ในวันนี้
TRS-80

3
ใช่ แต่ไม่ใช่ทุกยูนิกซ์รวมถึงโปรแกรมเสริมเช่น 'เปลี่ยนชื่อ' เมื่อวาง perl ไว้ในระบบ เช่น OSX ไม่มี "เปลี่ยนชื่อ" ในมัน
อิสระ

1
@William: ไวยากรณ์ดอกจันคู่มีให้เฉพาะใน Bash 4 ขึ้นไปและต่อเมื่อเปิดด้วยshopt -s globstar(โดยค่าเริ่มต้น) นอกจากนี้ Linux และ Unix ยังมีไดเรกทอรีมากกว่าโฟลเดอร์
Dennis Williamson

6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

ลองด้วยการechoเผชิญหน้าmvครั้งแรก

ปัญหาเกี่ยวกับต้นฉบับของคุณคือ " mv *.htm *.html" มีการ*จัดการโดยเชลล์ดังนั้นmvคำสั่งจะเห็นรายการของไฟล์. htm และ. html ทั้งหมดในไดเรกทอรีปัจจุบัน กล่าวอีกนัยหนึ่งเช่น " mv foo.htm bar.htm stuff.htm six.htm file.htm" mv รู้วิธีจัดการกับข้อโต้แย้งมากกว่า 2 ข้อหากตัวสุดท้ายคือไดเรกทอรี


1
คุณควรอ้างอิง "$ file" เพื่อจัดการช่องว่าง
Richard Hoskins

คำอธิบายของปัญหาดั้งเดิมควรเน้นหนักแน่นยิ่งขึ้น พฤติกรรมการขยายสัญลักษณ์ตัวแทนของเชลล์นี้น่าแปลกใจและไม่ง่ายสำหรับผู้ที่มาจาก Windows และเข้าใจว่าเชลล์ทำอะไรได้ชัดเจนว่าทำไมแอปพลิเคชันดั้งเดิมของใช้งานmvไม่ได้
Greg Hewgill

3

อีกตัวอย่างทุบตีบริสุทธิ์โดยใช้สตริงแทนที่

for file in *.htm; do mv $file ${file/htm/html}; done

พิเศษ - สิ่งนี้จะแทนที่การเกิดขึ้นทั้งหมดของสตริง

for file in *.htm; do mv $file ${file//htm/html}; done


1

เครื่องมือที่ดีที่สุดคือMMV

mmv \*.htm #1.html

ตัวอย่างการใช้งานอื่น ๆ (และเครื่องมืออื่น ๆ ) ใน " GNU / Linux เครื่องมือบรรทัดคำสั่งสรุป "


1
ตัวอย่างการใช้งานของคุณล้มเหลว #คุณจำเป็นต้องหลบหนี
Cristian Ciupitu

ไม่ทำงาน (ฉันทดสอบเสมอก่อนโพสต์บน SuperUser) ความต้องการที่จะหลบหนี # ขึ้นอยู่กับเชลล์ที่คุณใช้ (ฉันใช้ zsh)
bortzmeyer

0

util-ลินุกซ์ ngแพคเกจ (บน Fedora) มีrenameคำสั่งเดียวกับที่กล่าวถึงโดยTRS-80 คุณสามารถใช้สิ่งนี้:

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