วิธีลบอักขระที่ไม่ถูกต้องออกจากชื่อไฟล์ได้อย่างไร


47

ฉันมีไฟล์ที่มีตัวอักษรไม่ถูกต้องเช่นนี้

009_-_�%86ndringshåndtering.html

มันเป็นÆสิ่งที่ผิดพลาดในชื่อไฟล์

มีวิธีลบตัวอักขระที่ไม่ถูกต้องทั้งหมดหรือไม่?

หรืออาจtrจะใช้อย่างใด

echo "009_-_�%86ndringshåndtering.html" | tr ???

5
ตัวละครอาจจะไม่ "ไม่ถูกต้อง" อื่นระบบแฟ้มจะไม่เก็บไว้ (เว้นแต่คุณจะทำอะไรบางอย่างมันน่ารังเกียจไป FS) คุณลองเปลี่ยนภาษาของคุณ (เช่นเป็น UTF8) เพื่อแสดงชื่ออย่างถูกต้องหรือไม่?
James O'Gorman

คำตอบ:


41

วิธีหนึ่งจะอยู่กับ sed:

mv 'file' $(echo 'file' | sed -e 's/[^A-Za-z0-9._-]/_/g')

แทนที่fileด้วยชื่อไฟล์ของคุณแน่นอน สิ่งนี้จะแทนที่สิ่งที่ไม่ใช่ตัวอักษร, ตัวเลข, จุด, ขีดเส้นใต้หรือขีดกลางด้วยเครื่องหมายขีดล่าง คุณสามารถเพิ่มหรือลบตัวอักษรเพื่อให้เป็นไปตามที่คุณต้องการและ / หรือเปลี่ยนอักขระการแทนที่เป็นอย่างอื่นหรือไม่มีอะไรเลย


4
ฉันใช้:f='file'; mv 'file' ${f//[^A-Za-z0-9._-]/_}
หลุยส์

1
มองหาทางออกที่ดีที่สุดโดย H. Hess ด้านล่าง ... (และความคิดเห็นตลกของฉันพร้อม :))
Jan Sila

31

ฉันคิดว่าคุณอยู่ในกล่อง Linux และไฟล์ที่ทำในกล่อง Windows Linux ใช้ UTF-8 เป็นการเข้ารหัสอักขระสำหรับชื่อไฟล์ในขณะที่ Windows ใช้อย่างอื่น ฉันคิดว่านี่เป็นสาเหตุของปัญหา

ฉันจะใช้ "convmv" นี่คือเครื่องมือที่สามารถแปลงชื่อไฟล์จากการเข้ารหัสอักขระหนึ่งไปยังอีก สำหรับยุโรปตะวันตกสิ่งเหล่านี้ใช้ได้ผลตามปกติ:

convmv -r -f windows-1252 -t UTF-8 .
convmv -r -f ISO-8859-1 -t UTF-8 .
convmv -r -f cp-850 -t UTF-8 .

หากคุณต้องการติดตั้งบน Linux ที่ใช้ Debian คุณสามารถทำได้โดยการเรียกใช้:

sudo apt-get install convmv

มันใช้งานได้สำหรับฉันทุกครั้งและกู้คืนชื่อไฟล์ดั้งเดิม

ที่มา: LeaseWebLabs


1
สิ่งนี้ดูมีแนวโน้ม แต่มีแนวคิดใดที่จะบอกได้ว่าการเข้ารหัสคืออะไร ฉันมีไดเรกทอรีชื่อSave the current file in Word 97-2004 format\sco.workflowที่สร้างขึ้นบน Mac ของฉัน (ผ่าน Microsoft Office) และการเข้ารหัสข้างต้นไม่มีผลใด ๆ
Sridhar Sarnobat

เป็นค่าที่ชี้ให้เห็นว่าโดยค่าเริ่มต้น Convmv ทำงานในโหมด "ทดสอบ" ซึ่งเป็นเพียงการทำงานแบบแห้งและแจ้งให้คุณทราบว่าไฟล์ใดที่จะย้าย จากนั้นจะบอกให้คุณเรียกใช้อีกครั้งพร้อม--notestตัวเลือกในการเปลี่ยนชื่อไฟล์จริง
Kenny Rasschaert

16

ฉันคิดว่าคุณหมายถึงคุณต้องการสำรวจระบบไฟล์และแก้ไขไฟล์ดังกล่าวทั้งหมดหรือไม่

นี่คือวิธีที่ฉันทำ

find /path/to/files -type f -print0 | \
perl -n0e '$new = $_; if($new =~ s/[^[:ascii:]]/_/g) {
  print("Renaming $_ to $new\n"); rename($_, $new);
}'

ที่จะค้นหาไฟล์ทั้งหมดที่มีอักขระที่ไม่ใช่ ASCII และแทนที่อักขระเหล่านั้นด้วยเครื่องหมายขีดล่าง ( _) โปรดใช้ความระมัดระวังหากไฟล์ที่มีชื่อใหม่มีอยู่แล้วไฟล์นั้นจะถูกเขียนทับ สคริปต์สามารถแก้ไขเพื่อตรวจสอบกรณีเช่นนี้ แต่ฉันไม่ได้ใส่ไว้ในเพื่อให้ง่าย


13

ทำตามคำตอบได้ที่https://stackoverflow.com/questions/2124010/grep-regex-to-match-non-ascii-charactersคุณสามารถใช้:

rename 's/[^\x00-\x7F]//g' *

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

find . -exec rename 's/[^\x00-\x7F]//g' "{}" \;

คุณสามารถใช้อาร์กิวเมนต์ -n renameเพื่อทำการรันแบบแห้งและดูว่าอะไรจะเปลี่ยนแปลงโดยไม่เปลี่ยน


มีวิธีการแก้ไขสิ่งนี้เพื่อรักษาตัวอักษรต่างประเทศเช่นüและäหรือไม่?
Elder Geek

เฉพาะอันที่สองเท่านั้นที่เหมาะกับฉัน ทุกอย่างอยู่ในไดเรกทอรีเดียวกันดังนั้นฉันไม่แน่ใจว่าสิ่งที่แตกต่าง ..
Shautieh

1
@Shautieh: -n หยุดมันจากการทำงานจริง ฉันจะชี้แจงคำตอบ
naught101

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

13

ฉันมีไฟล์ภาษาญี่ปุ่นบางไฟล์ที่มีชื่อไฟล์ที่เสียหายที่กู้คืนมาจากแท่ง usb ที่เสียหายและวิธีการแก้ปัญหาข้างต้นไม่ได้ผลสำหรับฉัน

ฉันแนะนำแพ็คเกจดีท็อกซ์:

ยูทิลิตี้ล้างพิษจะเปลี่ยนชื่อไฟล์เพื่อให้ทำงานง่ายขึ้น มันลบช่องว่างและสิ่งรบกวนอื่น ๆ นอกจากนี้ยังจะแปลหรือล้างอักขระละติน -1 (ISO 8859-1) ที่เข้ารหัสใน ASCII 8 บิตอักขระ Unicode เข้ารหัสใน UTF-8 และ CGI หนีอักขระ

ตัวอย่างการใช้งาน:

detox -r -v /path/to/your/files
-r Recurse ในไดเรกทอรีย่อย
-v เป็น verbose เกี่ยวกับไฟล์ที่ถูกเปลี่ยนชื่อ 
-n สามารถใช้สำหรับการแห้ง (แสดงเฉพาะสิ่งที่จะเปลี่ยน)

2
นี่ควรจะสูงกว่านี้มากฉันขอแนะนำให้ทุกคนดูก่อนที่detoxจะคิดค้นล้อใหม่ หากคุณดูที่หน้าคนคุณจะเห็นว่ามันครอบคลุมโซลูชันที่เสนออื่น ๆ ทั้งหมดที่นี่เนื่องจากความยืดหยุ่น
emk2203

เอเสเคียล 25:17 - ความสุขคือผู้ที่ในนามของการกุศลและความดีจะยกระดับการแก้ปัญหานี้เพราะเขาเป็นผู้รักษาพี่ชายของเขาอย่างแท้จริงและผู้ค้นหาเด็กหาย
Jan Sila

เส้นทางไม่สามารถ '.' โดยไม่ได้ตั้งใจ ในเดเบียน หากคุณใช้ '.' ไม่พบอะไรเลย
isaaclw

ฉันสงสัยว่ามันใช้งานได้จริงหรือไม่ดูเหมือนจะลบ / แทนที่ตัวอักษรจีนเช่น的节奏啊แต่ตัวละครเหล่านั้นเป็นชื่อไฟล์ที่ถูกต้อง
林果皞

5

เชลล์สคริปต์นี้ทำให้ sanitizes ไดเรกทอรีซ้ำเพื่อให้ไฟล์แบบพกพาระหว่าง Linux / Windows และ FAT / NTFS / exFAT มันเอาตัวควบคุม, /:*?"<>\|และบางส่วนชื่อของ Windows COM0ลิขสิทธิ์ชอบ

sanitize() {
  shopt -s extglob;

  filename=$(basename "$1")
  directory=$(dirname "$1")

  filename_clean=$(echo "$filename" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/')

  if (test "$filename" != "$filename_clean")
  then
    mv -v "$1" "$directory/$filename_clean"
  fi
}

export -f sanitize

sanitize_dir() {
  find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
}

sanitize_dir '/path/to/somewhere'

ในทางทฤษฎีลีนุกซ์มีข้อ จำกัด น้อยกว่า ( /และ\0ห้ามใช้อย่างเคร่งครัดในชื่อไฟล์) แต่ในทางปฏิบัติตัวละครหลายตัวอาจรบกวนคำสั่ง bash (เช่น*... ) ดังนั้นจึงควรหลีกเลี่ยงในชื่อไฟล์

แหล่งที่ดีสำหรับข้อ จำกัด ในการตั้งชื่อไฟล์:


1
มันคือสิ่งที่ฉันค้นหา! แต่เพิ่มคำพูดเพื่อสนับสนุน dirs กับช่องว่างค้นหา "$ 1" - ความลึก -exec bash -c 'sanitize "$ 0"' {} \;
mmv-ru

1

หากคุณต้องการจัดการบรรทัดใหม่ฝังตัวอักขระหลายไบต์ช่องว่างเครื่องหมายขีดกลางเครื่องหมายทับขวาและช่องว่างที่คุณต้องการสิ่งที่แข็งแกร่งกว่าให้ดูคำตอบนี้:
https://superuser.com/a/858671/365691

ฉันวางสคริปต์บน code.google.com หากใครสนใจ: rnf-bash-rename-script


สคริปต์ที่เชื่อมโยงที่นี่แก้ไขปัญหาให้ฉันได้
Jeremiah Rose

0

ฉันใช้สายการบินเดียวนี้เพื่อลบอักขระที่ไม่ถูกต้องในไฟล์คำบรรยาย:

for f in *.srt; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.]/./g' |sed 's/\.\.\././g' |sed 's/\.\././g'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done
  1. ประมวลผลไฟล์ * .srt เท่านั้น (* สามารถใช้แทน * .srt เพื่อประมวลผลทุกไฟล์)
  2. ลบอักขระอื่นทั้งหมดยกเว้นตัวอักษร A-Za-z, ตัวเลข 0-9 และมหัพภาค "."
  3. ลบช่วงเวลาสองหรือสามที่เป็นไปได้
  4. ตรวจสอบเพื่อดูว่าชื่อไฟล์มีอักขระที่ไม่ถูกต้อง
  5. หากเป็นจริงมันจะเปลี่ยนชื่อไฟล์ด้วยคำสั่ง mv จากนั้นส่งเอาต์พุตการเปลี่ยนแปลงที่ทำด้วยคำสั่ง echo

-2

สำหรับไฟล์ใน *; ทำ mv "$ file" $ (echo "$ file" | sed -e 's / [^ A-Za-z0-9. -] / / g'); เสร็จแล้ว


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