จะเปลี่ยนชื่อไฟล์และแทนที่ตัวอักษรได้อย่างไร?


11

ฉันมีกลุ่มไฟล์ที่มี:(โคลอน) อยู่ในชื่อ ฉันต้องการแทนที่:ด้วย-(เส้นประ)

มีวิธีง่าย ๆ ในการทำสคริปต์หรือไม่?

ตัวอย่างชื่อไฟล์: 2013-10-11:11:52:08_055456663_045585_.txt

คำตอบ:


17

1 ซับง่าย ๆ ควรทำ (สมมติว่า Posix- shshell ที่เข้ากันได้):

for f in *:*; do mv -v "$f" $(echo "$f" | tr ':' '-'); done

คำอธิบาย:

  • for ... in ...; do ...; doneเป็นห่วง

  • *:* จับคู่ไฟล์และไดเรกทอรีทั้งหมดในไดเรกทอรีปัจจุบันซึ่งมี:ชื่ออยู่

  • f ถูกกำหนดในแต่ละชื่อไฟล์ดังกล่าวในลูป

  • mvเปลี่ยนชื่ออาร์กิวเมนต์แรกเป็นอาร์กิวเมนต์ที่สอง -v(verbose) ขอให้พิมพ์สิ่งที่มันทำ; ตัวเลือกนี้มีเฉพาะGNU-utilsดังนั้นจึงพร้อมใช้งานบน Linux แต่ไม่ใช่ Solaris

  • $(...) รันรหัสใน sub-shell และทดแทนการส่งออก

  • echo พิมพ์อาร์กิวเมนต์ไปที่เอาต์พุตมาตรฐาน

  • tr อ่านเอาต์พุตมาตรฐานและแปลอักขระตามแผนที่ที่ให้มา

หากคุณกำลังใช้ทุบตีคุณสามารถหลีกเลี่ยงการวางไข่เปลือกพิเศษ ( $()) กับกระบวนการย่อย ( tr) โดยการแทนที่ด้วย$(...)${f//:/-}


+1 สำหรับคำตอบที่ใช้งานง่ายแม้ว่าจะสามารถทำได้ด้วยคำอธิบายเพิ่มเติมอีกเล็กน้อย เช่นfor f in... ห่วงเป็นห่วงซึ่ง iterates *:*กว่าไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันที่ไฟล์จะต้องมีการแข่งขัน (เกิดอะไรขึ้นกับ dirs ที่ตรงกัน?) คำสั่งย้ายเป็นไป NewName oldname $( subshell here )ที่ชื่อใหม่จะถูกสร้างขึ้นโดยการดำเนินการที่มีเปลือก สิ่งทีไม่ ...
Hennes

@Hennes: นี่คือsuperuser - ฉันต้องลงรายละเอียดเหล่านี้จริงๆเหรอ? โอ้เอาละคุณไปแล้ว ...
sds

ไม่ถ้ามีความต้องการที่แท้จริงฉันจะไม่ +1 +1 และฉันเข้าใจว่ามันทำอะไร ฉันคิดว่ามันดีสำหรับผู้อ่านคนอื่น ๆ
Hennes

2
คุณสามารถแทนที่$(echo "$f" | tr ':' '-')ด้วย"${f//:/-}"และหลีกเลี่ยงการเรียก subshell ไปป์และโปรแกรมภายนอก ฉันคิดว่านี่เป็นเรื่องน่าเบื่อ แต่ก็ใช่มั้ย ดูที่นี่
evilsoup

@evilsoup แน่นอน; มันไม่ได้สร้างความแตกต่างอย่างมากสำหรับชุดข้อมูลขนาดเล็ก (และชุดหนึ่งอาจช่วยให้สามารถอ่านได้) แต่คุณจะประหลาดใจที่มีบางสิ่งที่รวดเร็วเช่นนั้นเพิ่มเข้ามา เมื่อเร็ว ๆ นี้ฉันได้รับมัน เขียนสคริปต์ดังกล่าวว่าทั้งสองคำสั่งสตริงนวดง่ายไม่จำเป็นอีกต่อไปได้อย่างง่ายดายเวลาดำเนินการตัดโดย 90% หรือมากกว่าซึ่งในชุดข้อมูลขนาดใหญ่ที่แปลไปหลายนาทีของเวลา wallclock วิ่ง
CVn

6

ตามที่ระบุไว้ในโพสต์อื่นโดยฉันrenameเครื่องมือสามารถทำเคล็ดลับสำหรับคุณ คุณเพียงแค่ต้องพิมพ์ rename s/:/-/ <files to rename> นี้แทนที่ทุกเครื่องหมายจุดในทุกไฟล์ที่คุณชื่อในตอนท้ายคือ2013-10-*

นี่คือลิงค์ไปยังโพสต์อื่นของฉัน


1

ฉันแน่ใจว่าโปร UNIX สามารถทำได้ด้วยการทุบตี แต่นี่เป็นเวอร์ชั่นที่รวดเร็วและสกปรกของฉันกับทับทิม

path_to_files = "/home/username/wrongnames/"
filenames = `ls #{path_to_files}`.split
filenames.each do |fn|
  `mv #{path_to_files + fn} #{path_to_files + fn.gsub(/:/, "-")}`
end

ตั้งค่า path_to_files เป็นพา ธ ไปยังไฟล์ที่คุณใช้ผิด บันทึกรหัสข้างต้นในไฟล์ชื่อ rename.rb แล้ว:

username@machinename$ ruby rename.rb

@sds ให้คำตอบที่ดีกว่ามาก ฉันควรลบคำตอบของฉันหรือไม่ ฉันใหม่สำหรับ stackoverflow
shupru

1
ไม่มี มันยังคงมีค่าที่สำคัญ :)
Blacklight Shining

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

1

หากคุณมีไฟล์เพียงหนึ่งหรือสองสามไฟล์คุณสามารถเปลี่ยนชื่อได้ดังนี้

  1. p="201*"จัดเก็บรูปแบบของชื่อไฟล์ที่คุณกำหนดเป้าหมายเป็นตัวแปรนี้:
  2. เก็บชื่อไฟล์เก่าold_name=$(ls | grep $p)ที่คุณต้องการจะเปลี่ยนชื่อ:
  3. เก็บชื่อไฟล์ใหม่ด้วยการเปลี่ยนอักขระที่จำเป็น:

    new_name=$(ls | grep $p | sed 's/:/_/g')        # Using 'sed'
    
                OR
    
    new_name=$(ls | grep $p | tr ':' '_')           # Using 'tr'
    

โบนัสทำความสะอาด :
  หากเห็นแก่ความสม่ำเสมอคุณต้องการแทนที่เครื่องหมายขีดคั่น (-) พร้อมกับเครื่องหมายจุดคู่ (:) ด้วยเครื่องหมายขีดล่าง (_) คุณสามารถทำสิ่งนี้ได้:

    new_name=$(ls | grep $p | tr ':-' '_');

  ข หากคุณต้องการขีดเส้นใต้สุดท้าย (ก่อนหน้า.txt) หายไปให้ตั้งค่าnew_nameตัวแปรเป็น:

    new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./')
  1. ตอนนี้เปลี่ยนชื่อไฟล์ของคุณตามต้องการ: mv $old_name $new_name

         NB: mvจะล้มเหลวหากชื่อไฟล์ใด ๆ ในการดำเนินการเปลี่ยนชื่อนั้นมีspacesอยู่ในนั้น ในกรณีนั้นให้ตัดตัวแปรที่เหมาะสมในเครื่องหมายคำพูดเช่น:
mv "$old_name" $new_name หรือ mv $old_name "$new_name" OR mv "$old_name" "$new_name"


หนึ่งสมุทร

1a: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | sed 's/:/_/g'); mv $old_name $new_name

1b: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':' '_'); mv $old_name $new_name

2: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':-' '_'); mv $old_name $new_name

3: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./'); mv $old_name $new_name

0

ใช้renamer :

$ renamer --find ":" --replace "-" *

ฉันคิดว่าการติดตั้งสภาพแวดล้อม node.js ที่สมบูรณ์แบบสำหรับการเปลี่ยนชื่อไฟล์นั้นค่อนข้างมากเกินไป renameเป็นเครื่องมือที่ติดตั้งไว้ล่วงหน้าในลีนุกซ์หลายรุ่น แต่ฉันคิดว่าสำหรับ Windows เครื่องมือนี้อาจยอดเยี่ยม
noggerl

0

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

/superuser//a/858671/365691

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