หลีกเลี่ยงการแทนที่ช่องว่างเมื่อเปลี่ยนชื่อไฟล์


10

ฉันพยายามเปลี่ยนชื่อไฟล์เช่นนี้:

for file in *;
do
mv -i "$file" "$(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')";
done

แต่คำสั่งแทนที่ช่องว่างทั้งหมดที่มีsed_

ฉันจะแก้ไขsedคำสั่งเพื่อทำให้เป็นช่องว่างพร้อมกับอักขระที่ระบุได้อย่างไร ฉันลองใช้\sแล้วแต่ไม่ได้ผล ...

แก้ไข:
ตัวอย่างเช่นไฟล์trip: hill, ควรจะเปลี่ยนชื่อ: แต่คำสั่งดังกล่าวทำให้มันtrip_ hilltrip__hill


ฉันกำลังย้ายไฟล์บางไฟล์จาก linux ไปยัง Mac แต่ด้วยเหตุผลบางอย่างระบบ Mac ไม่สามารถอ่านชื่อไฟล์ทั้งหมดได้ดังนั้นฉันจึงพยายามเปลี่ยนชื่อไฟล์ การเพิ่มช่องว่างในคำสั่งด้านบนไม่ทำงาน และคุณถูกต้อง: ฉันต้องการแทนที่ตัวอักษรทั้งหมดด้วย '_' ยกเว้นที่ระบุไว้ และฉันไม่ทราบวิธีรวมอักขระที่ว่าง

โปรดทราบว่าฉันพยายามแทนที่ตัวอักษรทั้งหมดด้วย '_' ยกเว้นที่ระบุไว้ ไม่มีรูปแบบเฉพาะสำหรับไฟล์ที่ถูกเปลี่ยนชื่อดังนั้นฉันไม่สามารถใช้คำสั่ง perl นี้ได้

คำตอบ:


11

อย่าแยกชื่อไฟล์ด้วยsed! ผลลัพธ์ของecho "$file"อาจไม่น่าเชื่อถือ

renameใช้ ในวันที่ 17.10 คุณต้องติดตั้งก่อน

sudo apt install rename

แล้ว:

rename -n -- 's/[^-A-Za-z0-9_ .]/_/g' *

หมายเหตุ

  • ลบ-nหลังจากการทดสอบเพื่อเปลี่ยนชื่อไฟล์จริง
  • -- end-of-options ในกรณีที่ไฟล์ใด ๆ เริ่มต้นด้วย -
  • [^-A-Za-z0-9_ .]ตัวอักษรที่เราไม่ต้องการแทนที่ - ใส่-ก่อนหรือท้ายสุดดังนั้นจึงไม่สามารถระบุช่วงได้
  • สามารถรวมช่องว่างในชั้นเรียนได้
  • . ได้รับการปฏิบัติอย่างแท้จริง (ในบริบทอื่น ๆ มันหมายถึงตัวละครใด ๆ และจะต้องหลบหนี)

สิ่งนี้ยังใช้งานได้ในsed:

$ echo 'trip: hill' | sed 's/[^-A-Za-z0-9 _.]/_/g'
trip_ hill

ถ้าฉันเพิ่มช่องว่างท้ายรุ่นของคุณฉันได้รับข้อผิดพลาด:

$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._- ]/_/g'
sed: -e expression #1, char 22: Invalid range end

แต่-เมื่อสิ้นสุดการทำงาน:

$ echo 'trip: hill' | sed -e 's/[^A-Za-z0-9._ -]/_/g'
trip_ hill

ดังนั้นตำแหน่งของเครื่องหมายขีดคั่นอาจทำให้เกิดปัญหาของคุณเมื่อคุณเพิ่มพื้นที่ แต่คำแนะนำไม่ให้แยกชื่อไฟล์ย่อมาจาก!


คำสั่งนี้ใช้งานได้ขอบคุณ คุณได้ระบุข้อผิดพลาดอย่างชัดเจนในคำสั่งที่ฉันใช้ด้วย

2
ขอขอบคุณอีกครั้ง. โปรดทราบว่าไม่จำเป็นต้องใช้เครื่องหมายทับด้านหน้า '\' ในกรณีของการใช้ sed เพราะนี่จะเพิ่ม '\' ไปยังรายการตัวอักษรที่ไม่สนใจ

2
@latach นั่นเป็นแบ็กสแลช แต่คุณพูดถูก หลังจากการทดสอบและขุดไปรอบ ๆ ฉันพบว่า.ตัวอักษรในชั้นเรียนตัวอักษร TIL!
Zanna

2

คุณสามารถใช้เชลล์การขยายพารามิเตอร์ของ Bashสามารถทำการทดแทนได้:

for f in ./* ; do
    mv "$f" "${f//[^-A-Za-z0-9._ ]/_}"
done

เครื่องหมายทับคู่บอกให้แทนที่การจับคู่ทั้งหมดนอกจากนั้นไวยากรณ์จะตรงไปตรงมา

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