ในไดเรกทอรีฉันมี*.html
ไฟล์มากมาย ฉันต้องการเปลี่ยนชื่อพวกเขาทั้งหมดเป็น*.txt
ฉันจะทำสิ่งนั้นได้อย่างไร ฉันใช้เปลือก bash
ในไดเรกทอรีฉันมี*.html
ไฟล์มากมาย ฉันต้องการเปลี่ยนชื่อพวกเขาทั้งหมดเป็น*.txt
ฉันจะทำสิ่งนั้นได้อย่างไร ฉันใช้เปลือก bash
คำตอบ:
สำหรับวิธีการแก้ปัญหาที่ดีกว่า (มีฟังก์ชันการทำงานทุบตีเท่านั้นเมื่อเทียบกับสายภายนอก) ดูหนึ่งในคำตอบอื่น ๆ
ต่อไปนี้จะทำและไม่ต้องการให้ระบบมีrename
โปรแกรม (แม้ว่าคุณมักจะมีสิ่งนี้ในระบบ):
for file in *.html; do
mv "$file" "$(basename "$file" .html).txt"
done
แก้ไข:ตามที่ระบุไว้ในความคิดเห็นนี้ไม่ทำงานสำหรับชื่อไฟล์ที่มีช่องว่างในพวกเขาโดยไม่ต้องอ้างอิงที่เหมาะสม (ตอนนี้เพิ่มด้านบน) เมื่อทำงานอย่างหมดจดกับไฟล์ของคุณที่คุณรู้ว่าไม่มีช่องว่างในชื่อไฟล์สิ่งนี้จะใช้ได้ แต่เมื่อใดก็ตามที่คุณเขียนบางสิ่งที่อาจนำมาใช้ซ้ำในภายหลังอย่าข้ามการอ้างอิงที่เหมาะสม
ren *.a *.b
$()
แทนไวยากรณ์ backtick ดั้งเดิม ปรับปรุงความสามารถในการอ่านและทำให้ไวยากรณ์มีความคลุมเครือน้อยลงเมื่อคุณมีอักขระที่ต้องใช้เครื่องหมายแบ็กสแลชเพื่อให้เป็นตัวอักษรในการทดแทนคำสั่งด้วยตัวหลัง
หากใช้ bash คุณไม่จำเป็นต้องใช้คำสั่งภายนอกเช่น sed, basename, rename, expr ฯลฯ
for file in *.html
do
mv "$file" "${file%.html}.txt"
done
"${file%.*}.txt"
แต่สิ่งนี้อาจเป็นอันตรายสำหรับไฟล์ที่ไม่มีนามสกุลไฟล์เลย
$
การดัดผมด้านใน!
--
"โอเปอเรเตอร์": mv - "$ file" "$ {file% .html} .txt" โอเปอเรเตอร์นั้นป้องกันชื่อไฟล์ที่ขึ้นต้นด้วย a '-' จากการแยกวิเคราะห์โดย mv เป็นอาร์กิวเมนต์
rename 's/\.html$/\.txt/' *.html
ทำสิ่งที่คุณต้องการ
สิ่งนี้ใช้ได้กับฉันใน OSX จาก. txt ถึง. txt_bak
find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \;
.txt
เพื่อ.txt_bak
คุณเพียงแค่ต้อง concatenate _bak
;)
.scss
เป็น.sass
(หลังจากการแปลงในสถานที่ ... ):find . -name '*.scss' -exec sh -c 'mv "$0" "${0%.scss}.sass"' {} \;
คุณต้องการใช้rename
:
rename -S .html .txt *.html
นี้ไม่ตรงกับสิ่งที่คุณต้องการ - มันจะเปลี่ยนนามสกุลจาก.html
ไปสำหรับไฟล์ทั้งหมดที่ตรงกัน.txt
*.html
หมายเหตุ: Greg Hewgill ชี้ให้เห็นอย่างถูกต้องว่านี่ไม่ใช่ bash builtin; และเป็นคำสั่งแยก Linux หากคุณต้องการบางสิ่งบน Linux สิ่งนี้ก็ใช้ได้ดี หากคุณต้องการสิ่งที่ข้ามแพลตฟอร์มมากขึ้นลองดูคำตอบอย่างใดอย่างหนึ่ง
rename
โปรแกรมไม่เกี่ยวข้องbash
และไม่สามารถใช้ได้ในทุกแพลตฟอร์ม ฉันเห็นมันบน Linux เท่านั้น
rename -S .html .text *.html
ที่-S
ย่อมาจาก--subst-all
บน Mac ...
brew install rename
rename -S .html .txt *.html
สำหรับผู้ใช้ Ubuntu:
rename 's/\.html$/\.txt/' *.html
นี่เป็นทางออกที่ลื่นที่สุดที่ฉันพบว่าทำงานได้บน OSX และ Linux และมันก็ทำงานได้ดีกับ git เช่นกัน!
find . -name "*.js" -exec bash -c 'mv "$1" "${1%.js}".tsx' - '{}' \;
และด้วยคอมไพล์:
find . -name "*.js" -exec bash -c 'git mv "$1" "${1%.js}".tsx' - '{}' \;
นี่คือตัวอย่างของคำสั่งเปลี่ยนชื่อ:
rename -n ’s/\.htm$/\.html/’ *.htm
-n หมายความว่าเป็นการทดสอบการทำงานและจะไม่เปลี่ยนแปลงไฟล์ใด ๆ มันจะแสดงรายการของไฟล์ที่จะถูกเปลี่ยนชื่อหากคุณลบ -n ในกรณีข้างต้นมันจะแปลงไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันจากนามสกุลไฟล์ของ. htm เป็น. html
หากผลลัพธ์ของการทดสอบการทำงานด้านบนดูดีแล้วคุณก็สามารถเรียกใช้เวอร์ชั่นสุดท้ายได้:
rename -v ’s/\.htm$/\.html/’ *.htm
-v เป็นทางเลือก แต่เป็นความคิดที่ดีที่จะรวมไว้เพราะมันเป็นเร็กคอร์ดเดียวที่คุณจะมีการเปลี่ยนแปลงที่ทำโดยคำสั่งเปลี่ยนชื่อดังที่แสดงในตัวอย่างผลลัพธ์ด้านล่าง:
$ rename -v 's/\.htm$/\.html/' *.htm
3.htm renamed as 3.html
4.htm renamed as 4.html
5.htm renamed as 5.html
ส่วนที่อยู่ตรงกลางตรงกลางคือการแทนที่ Perl ด้วยนิพจน์ปกติโดยไฮไลต์ด้านล่าง:
rename -v ’s/\.htm$/\.html/’ *.htm
คำถามนี้พูดถึง Bash อย่างชัดเจน แต่ถ้าคุณมี ZSH ให้ใช้งานมันก็ค่อนข้างง่าย:
zmv '(*).*' '$1.txt'
หากคุณได้รับzsh: command not found: zmv
แล้วเพียงแค่เรียกใช้:
autoload -U zmv
จากนั้นลองอีกครั้ง
ขอบคุณบทความต้นฉบับนี้สำหรับคำแนะนำเกี่ยวกับ zmv
หลังจากการรวบรวมข้อมูลเว็บไซต์ของคนอื่นฉันจบลงด้วยไฟล์หลายพันไฟล์ที่ขาดนามสกุล. html ข้ามไดเรกทอรีย่อยกว้าง ๆ
หากต้องการเปลี่ยนชื่อพวกเขาทั้งหมดในนัดเดียวยกเว้นไฟล์ที่มีนามสกุล. html อยู่แล้ว (ส่วนใหญ่ไม่มีเลย) สิ่งนี้ใช้ได้กับฉัน:
cd wwwroot
find . -xtype f \! -iname *.html -exec mv -iv "{}" "{}.html" \; # batch rename files to append .html suffix IF MISSING
ในกรณีของ OP ฉันอาจแก้ไขเล็กน้อยเพื่อเปลี่ยนชื่อไฟล์ * .txt เช่น:
find . -xtype f -iname *.txt -exec filename="{}" mv -iv ${filename%.*}.{txt,html} \;
พัง (Hammertime!):
-iname * .txt
- หมายถึงพิจารณาเฉพาะไฟล์ที่ลงท้ายด้วย. txt แล้ว
mv -iv "{} {txt, HTML}." - เมื่อพบ {. ชื่อไฟล์% *} ผ่าน {} เป็นชื่อไฟล์, $ สารสกัดจาก basename โดยไม่ต้องขยายใด ๆ ในรูปแบบพารามิเตอร์mv bashใช้ {txt, html} เพื่อเขียนซ้ำเป็นพารามิเตอร์สองตัวดังนั้นคำสั่งสุดท้ายจะทำงานเป็น:mv -iv "filename.txt" "filename.html"
แก้ไขตามต้องการ: จัดการกับช่องว่างในชื่อไฟล์
คำสั่งmmv
ดูเหมือนว่าจะทำภารกิจนี้ได้อย่างมีประสิทธิภาพมากในการเป็นจำนวนมากของไฟล์ (นับหมื่นในครั้งที่สอง) ตัวอย่างเช่นหากต้องการเปลี่ยนชื่อ.xml
ไฟล์ทั้งหมดเป็นไฟล์ให้.html
ใช้สิ่งนี้:
mmv ";*.xml" "#1#2.html"
;
จะตรงกับเส้นทางที่*
จะตรงกับชื่อไฟล์และสิ่งเหล่านี้จะเรียกว่า#1
และ#2
ในการเปลี่ยนชื่อ
คำตอบที่อ้างอิงจากexec
ไปป์หรือช้าเกินไปหรือล้มเหลวในไฟล์จำนวนมาก
ลองสิ่งนี้
rename .html .txt *.html
การใช้งาน:
rename [find] [replace_with] [criteria]
สายไปงานเลี้ยงเล็กน้อย คุณสามารถทำได้ด้วย xargs:
ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {}
หรือถ้าไฟล์ทั้งหมดของคุณอยู่ในบางโฟลเดอร์
ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {}
ls
คำสั่งนี้ไร้สาระ: มันใช้กับ glob ls
แทนการใช้ glob โดยตรง สิ่งนี้จะแตกด้วยชื่อไฟล์ที่มีช่องว่างเครื่องหมายคำพูดและ (เนื่องจากไม่มีเครื่องหมายคำพูด) อักขระ glob
นี่เป็นวิธีที่ดีในการแก้ไขส่วนขยายหลายรายการพร้อมกัน:
for fname in *.{mp4,avi}
do
mv -v "$fname" "${fname%.???}.mkv"
done
หมายเหตุ: ระวังขนาดส่วนขยายให้เท่ากัน (the ???)
ดี & เรียบง่าย!
find . -iname *.html -exec mv {} "$(basename {} .html).text" \;
หากคุณต้องการ PERL มีเป็น Perl สคริปต์สั้น ๆ (เขียนโดยแลร์รี่วอลล์, ผู้สร้าง PERL) ที่จะทำสิ่งที่คุณต้องการที่นี่: tips.webdesign10.com/files/rename.pl.txt
สำหรับตัวอย่างของคุณต่อไปนี้ควรทำเคล็ดลับ:
rename.pl 's/html/txt/' *.html
เช่นเดียวกับสิ่งที่เคยแนะนำมานี่คือวิธีที่ฉันทำ:
find . -name '*OldText*' -exec sh -c 'mv "$0" "${0/OldText/NewText}"' {} \;
ฉันตรวจสอบครั้งแรกกับ
find . -name '*OldText*' -exec sh -c 'echo mv "$0" "${0/OldText/NewText}"' {} \;
หนึ่งบรรทัดไม่มีลูป:
ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
ตัวอย่าง:
$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json ac8453e2-0d82-4d43-b80e-205edb754700.json
$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt ac8453e2-0d82-4d43-b80e-205edb754700.txt
น่าเสียดายที่การพกพาสะดวก คุณอาจต้องใช้เวทมนตร์ expr นิดหน่อย
for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done
ลบเสียงก้องเมื่อคุณมีความสุขมันทำในสิ่งที่คุณต้องการ
แก้ไข: basename
อาจจะอ่านได้มากกว่านี้เล็กน้อยสำหรับกรณีนี้แม้ว่าexpr
โดยทั่วไปจะมีความยืดหยุ่นมากกว่า
นี่คือสิ่งที่ฉันใช้ในการเปลี่ยนชื่อ.edge
ไฟล์เป็น.blade.php
for file in *.edge; do mv "$file" "$(basename "$file" .edge).blade.php"; done
ทำงานเหมือนจับใจ
นอกจากนี้คุณยังสามารถสร้างฟังก์ชั่นใน Bash เพิ่มไปยัง.bashrc
หรือบางสิ่งบางอย่างแล้วใช้งานได้ทุกที่ที่คุณต้องการ
change-ext() {
for file in *.$1; do mv "$file" "$(basename "$file" .$1).$2"; done
}
การใช้งาน:
change-ext css scss
แหล่งที่มาของรหัสในการทำงาน: https://stackoverflow.com/a/1224786/6732111
เปลี่ยนชื่อนามสกุลไฟล์สำหรับไฟล์ทั้งหมดภายใต้ไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยโดยไม่มีแพ็คเกจอื่น ๆ (ใช้เชลล์สคริปต์เท่านั้น):
สร้างเชลล์สคริปต์rename.sh
ภายใต้ไดเรกทอรีปัจจุบันด้วยรหัสต่อไปนี้:
#!/bin/bash
for file in $(find . -name "*$1"); do
mv "$file" "${file%$1}$2"
done
./rename.sh .old .new
เรียกใช้งานโดย
เช่น. ./rename.sh .html .txt