เปลี่ยนชื่อไฟล์ซ้ำ (เปลี่ยนนามสกุล) ใน Linux


21

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

find . -name "*.andnav" -exec rename .andnav .tile {} \;
syntax error at (eval 1) line 1, near "."

...

rename -nv 's/\.andnav$/\.tile/i' *.andnav
0.png.andnav renamed as 0.png.tile

1
คุณมี Debian renameหรือ Red Hat renameหรือไม่
Ignacio Vazquez-Abrams

@Ignacio: Ubuntu = Debian?
endolith

ใช่ Ubuntu เป็นอนุพันธ์ของเดเบียน
Ignacio Vazquez-Abrams

คำตอบ:


23

คิดออก

find . -name "*.andnav" -exec rename -v 's/\.andnav$/\.tile/i' {} \;
./0/0.png.andnav renamed as ./0/0.png.tile
./0/1.png.andnav renamed as ./0/1.png.tile
./1/0.png.andnav renamed as ./1/0.png.tile
./1/1.png.andnav renamed as ./1/1.png.tile

แน่นอนลบ -v เมื่อทำจริงหรือจะเสียเวลาในการแสดงไฟล์ทั้งหมด


13

สิ่งที่ต้องการ:

find . -name '*.andnav' -exec sh -c 'mv "$0" "${0%.andnav}.tile"' {} \;

อันนี้ใช้ได้ดีที่สุดสำหรับฉัน
cwd


4

ฉันพบวิธีนี้ง่ายและง่ายต่อการอ่าน:

find . -name "*.andnav" | rename "s/\.andnav$/.tile/"

อย่างน้อยการเปลี่ยนชื่อ Ubuntu derivations จะใช้รายการไฟล์จาก STDIN หากไม่มีในบรรทัดคำสั่ง และสามารถทดสอบได้อย่างง่ายดายด้วย:

find . -name "*.andnav" | rename -vn "s/\.andnav$/.tile/"

จนกว่าคุณจะทำให้ถูกต้อง


1

เปลี่ยนชื่อไฟล์และไดเรกทอรีด้วย find -execdir | rename

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

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find . -depth -execdir rename 's/findme/replaceme/' '{}' \;

น่ากลัว-execdirตัวเลือกที่ไม่ได้cdลงในไดเรกทอรีก่อนดำเนินการคำสั่งซึ่งแตกต่างจากrename-exec

-depth ตรวจสอบให้แน่ใจว่าการเปลี่ยนชื่อเกิดขึ้นครั้งแรกกับเด็ก ๆ และจากนั้นในผู้ปกครองเพื่อป้องกันปัญหาที่อาจเกิดขึ้นกับไดเรกทอรีหลักที่ขาดหายไป

-execdir จำเป็นต้องมีเนื่องจากการเปลี่ยนชื่อเล่นได้ไม่ดีกับเส้นทางเข้าที่ไม่ใช่ชื่อไฟล์เช่นต่อไปนี้ล้มเหลว:

rename 's/findme/replaceme/g' acc/acc

การPATHแฮ็คเป็นสิ่งจำเป็นเนื่องจาก-execdirมีข้อเสียเปรียบที่น่ารำคาญอย่างหนึ่ง: findมีความเห็นอย่างมากและปฏิเสธที่จะทำอะไรด้วย-execdirหากคุณมีเส้นทางญาติในPATHตัวแปรสภาพแวดล้อมของคุณเช่น./node_modules/.binล้มเหลวด้วย:

find: พา ธ สัมพัทธ์ './node_modules/.bin' รวมอยู่ในตัวแปรสภาพแวดล้อม PATH ซึ่งไม่ปลอดภัยเมื่อใช้ร่วมกับการดำเนินการ -execdir ของการค้นหา โปรดลบรายการนั้นออกจาก $ PATH

ดูเพิ่มเติมที่: https://askubuntu.com/questions/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378

-execdirเป็น GNU พบส่วนขยายไปยัง POSIX renameเป็นภาษา Perl และมาจากrenameแพ็คเกจ ทดสอบใน Ubuntu 18.10

เปลี่ยนชื่อวิธีแก้ปัญหา lookahead

หากเส้นทางอินพุตของคุณไม่ได้มาจากfindหรือหากคุณมีความรำคาญในเส้นทางสัมพัทธ์เพียงพอเราสามารถใช้ Perl lookahead เพื่อเปลี่ยนชื่อไดเรกทอรีอย่างปลอดภัยใน:

git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'

ฉันไม่พบอะนาล็อกที่ใช้งานได้ง่าย-execdirด้วยxargs: Xargs: เปลี่ยนไดเรกทอรีการทำงานเป็นพา ธ ไฟล์ก่อนดำเนินการ

sort -rเป็นสิ่งจำเป็นเพื่อให้มั่นใจว่าไฟล์มาหลังจากไดเรกทอรีของตนตั้งแต่เส้นทางอีกต่อมาหลังจากที่คนสั้นด้วยคำนำหน้าเดียวกัน

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