วิธีแทนที่หนึ่งอักขระด้วยอักขระอื่นในชื่อไฟล์ทั้งหมดของไดเรกทอรีปัจจุบันได้อย่างไร


41

คุณจะเปลี่ยนชื่อไฟล์ / โฟลเดอร์ย่อยทั้งหมดในโฟลเดอร์ปัจจุบันได้อย่างไร

ให้บอกว่าฉันมีหลายไฟล์และส่วนย่อยที่มีช่องว่างและฉันต้องการแทนที่ช่องว่างทั้งหมดด้วยการขีดเส้นใต้

File 1
File 2
File 3
Dir 1
Dir 3

ควรเปลี่ยนชื่อเป็น

File_1
File_2
File_3
Dir_1
Dir_3

คำตอบ:


36

หากคุณต้องการเปลี่ยนชื่อไฟล์ในไดเรกทอรีย่อยเช่นกันและfindรองรับภาค-execdirแสดงคุณก็สามารถทำได้

find /search/path -depth -name '* *' \
    -execdir bash -c 'mv -- "$1" "${1// /_}"' bash {} \;

ขอบคุณ @glenn jackman ที่แนะนำ-depthตัวเลือกสำหรับfindและทำให้ฉันคิดว่า

โปรดทราบว่าในบางระบบ (รวมถึง GNU / Linux) findอาจล้มเหลวในการค้นหาไฟล์ที่มีชื่อมีช่องว่างและลำดับของไบต์ที่ไม่ได้สร้างอักขระที่ถูกต้อง (โดยทั่วไปกับไฟล์สื่อที่มีชื่อที่มีอักขระที่ไม่ใช่ ASCII เข้ารหัสในชุดอักขระ) แตกต่างจากที่ตั้งของ) การตั้งค่าภาษาเป็นC(ในLC_ALL=C find...) จะแก้ไขปัญหา


คุณจะต้องใช้find -maxdepth 1เพื่อทำสิ่งที่ OP ถามเกี่ยวกับการดำเนินงานในโฟลเดอร์ปัจจุบัน
คาเลบ

1
ใช้หาของตัวเลือกและคุณสามารถได้รับการกำจัดของ-depth sort
เกล็นแจ็

@glenn jackman: ขอบคุณตอนนี้ฉันเข้าใจว่าวิธีการแก้ปัญหาของฉันผิด
enzotib

2
เปลี่ยน-name '* *'เป็น-name '*_*'และเปลี่ยน"${1// /_}"เป็น"${1//_/.}"
enzotib

1
@kroiz: มันถูกเรียกว่า "การแทนที่รูปแบบ" คุณสามารถค้นหาได้ในbashหน้าคน
enzotib

34

ในเชลล์ใด ๆ คุณสามารถวนซ้ำไฟล์ที่ชื่อมีช่องว่าง การแทนที่ช่องว่างด้วยการขีดล่างทำได้ง่ายใน bash, ksh และ zsh ด้วย${VARIABLE//PATTERN/REPLACEMENT}โครงสร้าง

for x in *" "*; do
  mv -- "$x" "${x// /_}"
done

บน Debian, Ubuntu และอนุพันธ์คุณสามารถใช้ Perl rename(ดิสทริบิวชันอื่น ๆ จัดส่งโปรแกรมอื่นเป็นrename, และโปรแกรมนั้นไม่มีประโยชน์ที่นี่)

rename 's/ /_/g' *

โซลูชั่น zsh บังคับ:

autoload zmv
zmv '(*)' '${1// /_}'

โซลูชัน POSIX ที่จำเป็น:

for x in *" "*; do
  y=$(printf %sa "$x" | tr " " "_")
  mv -- "$x" "${y%a}"
done

'g' ในตอนท้ายของคำสั่ง "rename" หมายถึงอะไร? ฉันไม่เห็นมันในคู่มือ
JulianLai

วิธีการเปลี่ยนชื่อไดเรกทอรีเท่านั้น? ฉันไม่ต้องการเปลี่ยนชื่อไฟล์
JulianLai

@JulianLai s/…/…/gหมายถึงการแทนที่สิ่งที่เกิดขึ้นทั้งหมด มันไม่สามารถอธิบายได้ดีมากในคู่มือการใช้งาน หากคุณต้องการเปลี่ยนชื่อไดเรกทอรีมีหลายวิธีโปรดค้นหามัน (ฉันคิดว่าฉันเคยเห็นมาก่อน) และถ้าคุณไม่สามารถหามันถามคำถามใหม่
Gilles 'หยุดความชั่วร้าย'

ดี ... นี้ช่วยให้ผมเปลี่ยนชื่อทั้งหมดไป_MG_blah.JPG IMG_blah.JPG
Abinash Dash

13

คุณสามารถใช้renameสิ่งนี้ (นี่คือการสมมติจากutil-linuxไม่ใช่ไม่ใช่perl):

cd /path/to/dir
rename ' ' _ *\ *

ซึ่งจะค้นหาพื้นที่ไฟล์และไดเรกทอรีทั้งหมดในชื่อและแทนที่พื้นที่ด้วยเครื่องหมายขีดล่าง เนื่องจากมันใช้การจับคู่ไฟล์ glob คุณต้องอยู่ในไดเรกทอรีที่ถูกต้องเพื่อเริ่มต้น

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

cd /path/to/dir
shopt -s globstar
rename ' ' _ **/*\ *
!!; !!

2
renameจะเปลี่ยนชื่อไฟล์ที่ระบุโดยแทนที่การเกิดขึ้นครั้งแรกของจากในชื่อของพวกเขาโดยเป็น ” ดังนั้นนี้จะทำงานเฉพาะสำหรับไฟล์ที่มีพื้นที่เดียวในชื่อของพวกเขา (คุณสามารถโทรหาrenameลูปได้ แต่มันไม่ใช่เครื่องมือที่ถูกต้องที่นี่)
Gilles 'ดังนั้นหยุดความชั่วร้าย'

2

ตัวเลือกอื่นจะเป็นmmvถ้าติดตั้ง

mmv \*\ \* \#1_#2

การเปลี่ยนแปลงนี้เป็นการเว้นวรรคแรกเป็น a _เท่านั้น แต่จะไม่ทำงานกับชื่อที่มีหลายช่องว่าง
Gilles 'หยุดชั่วร้าย'

โอ้คุณพูดถูก ขอโทษสำหรับความสับสน.
glglgl

1

บน Debian / Ubuntu สร้างตามคำตอบของ Caleb และ Gilles นี่คือสิ่งที่ฉันใช้เพื่อเปลี่ยนชื่อไฟล์ซ้ำ:

cd /path/to/dir
shopt -s globstar
rename 's/ /_/g' **

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

rename -n 's/ /_/g' **

ทราบอีก: การตั้งค่าglobstarทำให้**ตรงกับไฟล์ในไดเรกทอรีย่อยทั้งหมดดังนั้นหากเพียงไดเรกทอรีปัจจุบันเป็นที่ต้องการไม่ได้ตั้งค่า GLOBSTAR หรือใช้แทน***

อีกหนึ่งหมายเหตุ: renameคำสั่งจะต้องมีการเรียกใช้มากกว่าหนึ่งครั้งสำหรับไฟล์ที่มีคำค้นหาหลายครั้ง


ใช้งานได้เฉพาะในกรณีที่ไดเรกทอรีไม่มีช่องว่าง (เปลี่ยนชื่อของa b/c dเพื่อa_b/c_dจะไม่ทำงานคุณจะต้องแรกที่จะเปลี่ยนชื่อa b/c dไปa b/c_dแล้วa bไปa_b)
Stéphane Chazelas

@Stephane: การรันrenameคำสั่งเดียวกันสองครั้งหมายความว่าอย่างไร
Markus Pscheidt

ดีมากขึ้นหลายครั้งเช่นเดียวกับที่มีระดับของไดเรกทอรีที่มีช่องว่าง เป็นการดีที่คุณต้องการสำรวจความลึกของไดเรกทอรีก่อนและแปลงเฉพาะชื่อไฟล์พื้นฐานเช่นเดียวกับในโซลูชันที่ยอมรับ นอกจากนี้โปรดทราบว่า bash's **ไม่รวม dotfiles และ traverses symlinks
Stéphane Chazelas

0

หากคุณไม่ใช่แฟลชในนิพจน์ทั่วไป (ฉันไม่ใช่!) และคุณสามารถเรียกใช้แอปพลิเคชันที่ออกแบบมาสำหรับ kde (ไม่ว่าคุณจะใช้เดสก์ท็อป kde - k หรือคุณติดตั้งไลบรารี) แล้ว krename เป็นโปรแกรมกราฟิกที่ยอดเยี่ยม ช่วยให้คุณเห็นก่อนและหลังก่อนที่คุณจะยอมรับการเปลี่ยนแปลง มันมีการแปลงอย่างง่ายจำนวนหนึ่งเป็นทางเลือกและยังรองรับการแสดงออกปกติ คุณสามารถรวมการแปลงแบบต่อเนื่องหลาย ๆ แบบไว้ในการเปลี่ยนชื่อเดียวดังนั้นคุณไม่จำเป็นต้องออกแบบการแปลงแบบซับซ้อนเดียวที่ทำได้ทั้งหมดในครั้งเดียว นอกจากนี้ยังมีตัวเลือกในการเปลี่ยนชื่อไฟล์เดิมต่อไปหลังจากเปลี่ยนชื่อถูกนำไปใช้

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

http://www.krename.net/

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