การเปลี่ยนชื่อไฟล์ในโฟลเดอร์เป็นหมายเลขต่อเนื่อง


230

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

ตัวอย่างเช่นsadf.jpgการ0001.jpg, wrjr3.jpgการ0002.jpgและอื่น ๆ จำนวนเลขศูนย์นำไปขึ้นอยู่กับจำนวนของไฟล์ (ความจำเป็นในการ zeroes พิเศษถ้าไม่จำเป็นต้องไม่ได้)


ฉันได้ดูstackoverflow.com/questions/880467/…แต่ฉันไม่สามารถใช้งานได้สำหรับฉัน
Gnutt

1
Linux / Unix ไม่ได้จัดเก็บวันที่สร้าง
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

1
ls -1tr | เปลี่ยนชื่อ -v 's /.*/ $ i ของเราถ้า (! $ i) {$ i = 1;} sprintf ("% 04d.jpg", $ i ++) / e'
maXp

คำตอบ:


313

ลองใช้การวนซ้ำletและprintfสำหรับการขยาย:

a=1
for i in *.jpg; do
  new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
  mv -i -- "$i" "$new"
  let a=a+1
done

การใช้-iแฟล็กป้องกันการเขียนทับไฟล์ที่มีอยู่โดยอัตโนมัติ


4
คุณสามารถทำได้printf -v new "%04d.jpg" ${a}เพื่อใส่ค่าลงในตัวแปร และ((a++))ทำงานเพื่อเพิ่มตัวแปร นอกจากนี้สิ่งนี้จะไม่ทำตามลำดับวันที่สร้างหรือย่อเล็กสุดซึ่งเป็นสิ่งที่ OP ระบุ อย่างไรก็ตามควรสังเกตว่า Linux / Unix ไม่ได้จัดเก็บวันที่สร้าง
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

3
จำเป็นต้องใช้เครื่องหมายคำพูดคู่ล้อม mv เพื่อให้ทำงานในสภาพแวดล้อมทุบตีของฉัน mv "$ {i}" "$ {new}"
Gary Thomann

2
อาจเป็น Cygwin (แม้ว่าพฤติกรรมของเทอร์มินัลจะเหมือนกับเชลล์ Unix ทั่วไป) แต่ดูเหมือนว่าจะมีปัญหาเมื่อมีช่องว่างในชื่อไฟล์
Geesh_SO

2
มันอาจเป็นที่พึงปรารถนาที่จะใช้mv -- "$i" "$new"เพื่อจัดการชื่อไฟล์แหล่งที่มาที่เริ่มต้นด้วยเครื่องหมายขีดกลาง ตามที่เป็นอยู่mvจะพยายามแยกชื่อไฟล์ดังกล่าวเป็นชุดธง
Charles Duffy

2
ฉันหลงทางประมาณ 800 ไฟล์โดยสังเขป ฉันคิดว่า-iควรรวมอยู่ในคำตอบและควรเขียนใหม่ตามนั้น มันจะปลอดภัยมากขึ้น :(
KrIsHnA

269

ความงามในหนึ่งบรรทัด:

ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done 

คุณสามารถเปลี่ยน.extด้วย.png, .jpgฯลฯ


4
คำอธิบาย :) ฉันใช้สิ่งนี้กับ git shell บน windows ใช้งานได้ดีมาก! ^^
Mr.K

4
ใช้งานได้ดี ความงามในหนึ่งบรรทัด ฉันเพิ่ม ls -tr เพื่อรับไฟล์ตามเวลาที่แก้ไขล่าสุด
Ranjith Siji

32
เพิ่ม printf เช่นนี้: ls | cat -n | while read n f; do mv "$f" `printf "%04d.extension" $n`; doneเพื่อให้มีจำนวนศูนย์เบาะ
Seweryn Niemiec

8
คำเตือน: คุณอาจต้องการเพิ่ม-nคำสั่ง mv เพื่อป้องกันการเขียนทับไฟล์โดยไม่ตั้งใจ ค้นพบวิธีนี้ยาก!
Ian Danforth

4
รวบรวมข้อคิดเห็นที่ยอดเยี่ยมจากความคิดเห็นเกี่ยวกับคำตอบนี้และอื่น ๆ : ls -1prt | grep -v "/$" | cat -n | while read n f; do mv -n "${f}" "$(printf "%04d" $n).${f#*.}"; done ผลลัพธ์: (1) เรียงลำดับตามการปรับเปลี่ยนไฟล์ในภายหลังที่มีดัชนีภายหลัง (2) ไม่สนใจไดเรกทอรี - และไม่เรียกซ้ำ (3) ดัชนีแผ่น; (4) รักษานามสกุลเดิม
Jorge

63

ฉันชอบโซลูชันของ gauteh สำหรับความเรียบง่าย แต่มีข้อเสียเปรียบที่สำคัญ เมื่อทำงานกับไฟล์หลายพันไฟล์คุณจะได้รับข้อความ "รายการอาร์กิวเมนต์ยาวเกินไป" ( มากกว่านี้ ) และที่สองสคริปต์จะช้าลงอย่างมาก ในกรณีของฉันใช้ไฟล์ประมาณ 36.000 สคริปต์ย้ายประมาณ หนึ่งรายการต่อวินาที! ฉันไม่ได้จริงๆว่าทำไมนี้เกิดขึ้น แต่กฎที่ผมได้จากเพื่อนร่วมงานเป็น"findเป็นเพื่อนของคุณ"

find -name '*.jpg' | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command

ในการนับจำนวนไอเท็มและคำสั่ง build จะใช้gawk สังเกตความแตกต่างหลักแม้ว่า โดยค่าเริ่มต้นfindค้นหาไฟล์ในไดเรกทอรีปัจจุบันและไดเรกทอรีย่อยดังนั้นให้ จำกัด การค้นหาในไดเรกทอรีปัจจุบันเท่านั้นหากจำเป็น (ใช้man findเพื่อดูว่า)


7
ฉันแก้ไขเพื่อใช้หมายเลขแถวNRสำหรับคำสั่งที่สั้นกว่า gawk '{ printf "mv %s %04d.jpg\n", $0, NR }'
อภิวัฒน์จันทวิบูลย์

12
ช่องโหว่ความปลอดภัยขนาดใหญ่ที่นี่ $(rm -rf /).jpgคิดว่าถ้าคุณมีไฟล์ชื่อ
Charles Duffy

ขอบคุณสำหรับการชี้ให้เห็นว่าชาร์ลส์ คุณช่วยแนะนำวิธีแก้ปัญหาที่ปลอดภัยได้ไหม?
beibei2

2
หยุดพักในกรณีที่ชื่อไฟล์มีช่องว่าง ใช้เครื่องหมายคำพูดรอบชื่อไฟล์ต้นฉบับ printf "mv \"% s \ "% 04d.jpg \ n", $ 0, a ++
baskin

1
การforวนซ้ำไม่ได้ใช้เวลา 1 วินาทีต่อไฟล์โดยพูดอย่างเคร่งครัด ใช้เวลานานในการเรียกชื่อไฟล์ 36,000 ชื่อจากระบบไฟล์จากนั้นวนซ้ำอย่างรวดเร็วพอสมควร ระบบไฟล์จำนวนมากมีปัญหากับไดเรกทอรีขนาดใหญ่โดยไม่คำนึงถึงคำสั่งที่คุณใช้อย่างแม่นยำ แต่โดยทั่วไปfindจะเร็วกว่า shell wildcard เนื่องจากต้องดึงข้อมูลและเรียงลำดับรายการไฟล์ที่ตรงกัน
tripleee

30

ด้วยคำสั่ง "เปลี่ยนชื่อ"

rename -N 0001 -X 's/.*/$N/' *.jpg

หรือ

rename -N 0001 's/.*/$N.jpg/' *.jpg

32
My rename(Linux Mint 13) ของฉันไม่มี-Nตัวเลือก
ลุค H

ฉันสามารถ upvote เพียงพูดถึงคำสั่งเปลี่ยนชื่อฉันไม่เคยได้ยินมัน
user907860

8
ฉันสนใจที่จะรู้ว่าใครจะได้รับคำสั่งเปลี่ยนชื่อด้วยตัวเลือก -N Ubuntu 14.04 ของฉันไม่มี
Stephan Henningsen

1
ฉันรักrenameคำสั่ง แต่ฉันไม่เคยรู้เกี่ยวกับ-N! ขอบคุณ!
Dan Lecocq

1
มีอย่างน้อยสามเครื่องมือที่แตกต่างรู้จักกันในนาม renameลิงก์ที่โพสต์โดย @Bostrot นั้นเป็นเครื่องมือเปลี่ยนชื่ออีกอันหนึ่งและดูเหมือนว่า @RomanRhrnNesterov ใช้ลิงก์นั้น ¶สำหรับผู้ใช้ทั้งหมดrenameโดย Peder Stray และ Larry Wall (แพ็คเกจperl-renameบน arch linux และแพ็คเกจrenameบน debian / ubuntu): คุณสามารถกำหนด$Nตัวเอง:perl-rename '$N=sprintf("%04d",++$N); s/.*/$N.jpg/' *.jpg
Socowi

30

การใช้โซลูชัน Pero บน OSX จำเป็นต้องแก้ไขบางอย่าง ฉันใช้:

find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash

หมายเหตุ: แบ็กสแลชนั้นมีไว้เพื่อการต่อสาย

แก้ไข 20 กรกฎาคม 2558: รวมคำติชมของ @ klaustopher เพื่ออ้างถึง\"%s\"อาร์กิวเมนต์ของmvคำสั่งเพื่อรองรับชื่อไฟล์ที่มีช่องว่าง


3
เช่นเดียวกับวิธีการของ Pero มีช่องโหว่ด้านความปลอดภัยที่นี่ $(rm -rf /).jpgคิดว่าถ้าคุณมีไฟล์ชื่อ
Charles Duffy

ขอบคุณมันใช้งานได้ mvแต่คุณควรพูดอาร์กิวเมนต์แรก หากคุณมีไฟล์ชื่อเช่นsome thing.jpgสคริปต์ของคุณล้มเหลว นี่คือสิ่งที่ฉันใช้:find . -name '*.jpg' | awk 'BEGIN{ a=0 }{ printf "mv \"%s"\ wallpaper-%04d.jpg\n", $0, a++ }' | bash
klaustopher

ฉันอาจจะใช้-maxdepth 1เพื่อทำงานเฉพาะใน jpgs ในไดเรกทอรีปัจจุบันเพราะจะปลอดภัยกว่าขออภัย
Peter Perháč

หากคุณย้ายตัวไพพ์ไปยังจุดสิ้นสุดของบรรทัดก่อนหน้าคุณไม่จำเป็นต้องใช้แบ็กสแลชใด ๆ
tripleee

คุณอาจใช้ls -1 *.jpgแทนการค้นหามิฉะนั้นจะไม่ถูกจัดเรียง หรือเพิ่ม a |sort|awk ก่อนหน้า
JPT

28

bash one ที่เรียบง่ายมากที่ใช้เก็บนามสกุลเดิมเพิ่มเลขศูนย์นำหน้าและใช้งานได้ใน OSX:

num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done

รุ่นที่ง่ายกว่าของhttp://ubuntuforums.org/showthread.php?t=1355021


สิ่งที่ฉันกำลังมองหา ฉันชอบที่คุณสามารถตั้งค่าดัชนีเริ่มต้น
Jack Vial

2
โปรดทราบว่าสิ่งนี้จะไม่เก็บลำดับดั้งเดิมของไฟล์ไว้
Roy Shilkrot

@RoyShilkrot คุณหมายถึงอะไร» จะไม่รักษาคำสั่งเดิม «? Globs ใน bash และเชลล์ posix อื่น ๆ ขยายตามลำดับที่เรียงตามโลแคลของระบบ แน่นอนว่านี่ไม่ได้จัดเรียง9.extมาก่อน11.extแต่เครื่องมืออื่น ๆ (เช่นls) จะไม่ทำเช่นนั้น
Socowi

11

ในการทำงานในทุกสถานการณ์ให้ใส่ \ "สำหรับไฟล์ที่มีช่องว่างในชื่อ

find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash

3
ไม่ได้ครอบคลุมทุกสถานการณ์ ชื่อไฟล์ที่มีคำพูดตามตัวอักษรอาจหนีออกมาได้เล็กน้อยและเนื่องจากคุณใช้เครื่องหมายคำพูดคู่แทนที่จะเป็นเครื่องหมายคำพูดเดี่ยวการขยายเช่น$(rm -rf /)นั้นจึงยังคงได้รับเกียรติ
Charles Duffy

11

หากคุณrenameไม่สนับสนุน-Nคุณสามารถทำสิ่งนี้:

ls -1 -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e'

แก้ไขหากต้องการเริ่มต้นด้วยหมายเลขที่กำหนดคุณสามารถใช้รหัส (ดูค่อนข้างน่าเกลียด) ด้านล่างเพียงแค่แทนที่ 123 ด้วยหมายเลขที่คุณต้องการ:

ls -1 -c | xargs rename -n 's/.*/our $i; if(!$i) { $i=123; } sprintf("%04d.jpg", $i++)/e'

สิ่งนี้แสดงรายการไฟล์ตามลำดับเวลาการสร้าง (ใหม่สุดก่อนเพิ่ม-rใน ls เพื่อย้อนกลับเรียงลำดับ) จากนั้นส่งรายการไฟล์นี้เพื่อเปลี่ยนชื่อ เปลี่ยนชื่อใช้รหัส perl ใน regex เพื่อจัดรูปแบบและตัวนับที่เพิ่มขึ้น

อย่างไรก็ตามหากคุณกำลังจัดการกับภาพ JPEG ที่มีข้อมูล EXIF ​​ฉันขอแนะนำ exiftool

นี่คือจากเอกสาร exiftoolภายใต้ "ตัวอย่างการเปลี่ยนชื่อ"

   exiftool '-FileName<CreateDate' -d %Y%m%d_%H%M%S%%-c.%%e dir

   Rename all images in "dir" according to the "CreateDate" date and time, adding a copy number with leading '-' if the file already exists ("%-c"), and
   preserving the original file extension (%e).  Note the extra '%' necessary to escape the filename codes (%c and %e) in the date format string.

ฉันจะเริ่มต้นด้วยหมายเลขเฉพาะโดยใช้renameอย่างไร
ม.ค.

6

บน OSXให้ติดตั้งสคริปต์การเปลี่ยนชื่อจาก Homebrew:

brew install rename

จากนั้นคุณสามารถทำได้อย่างง่ายดายจริง ๆ ขัน:

rename -e 's/.*/$N.jpg/' *.jpg

หรือเพื่อเพิ่มคำนำหน้าดี:

rename -e 's/.*/photo-$N.jpg/' *.jpg

3
นั่นเป็นสคริปต์ที่ยอดเยี่ยมและมันก็ขึ้นอยู่กับ Perl เท่านั้น ชงใช้งานได้กับ mac เท่านั้น แต่คุณสามารถคว้าได้จาก github ( github.com/ap/rename ) และใช้กับ Linux หรือ Windows
Tim Danner

3
มันไม่ได้ผลสำหรับฉัน ฉันได้Global symbol "$N" requires explicit package name (did you forget to declare "my $N"?) at (user-supplied code).
Anthony Chung

ในฐานะผู้ใช้ Mac ฉันยินดีที่จะรายงานว่าแอปพลิเคชันการเปลี่ยนชื่อที่เชื่อมโยงกับ @TimDanner นั้นพกพาได้ง่ายมันเป็นเรื่องง่ายเหมือนกับการดาวน์โหลด Zip Zip และวางยูทิลิตี้การเปลี่ยนชื่อในไดเรกทอรีที่เส้นทางโปรไฟล์ทุบตี และมันใช้งานได้ทันที ฉันประหลาดใจที่ไม่มีใน MacPorts ฉันคิดว่ามันแปลกมากที่ฉันมี BSD manpage สำหรับ Rename (2) แต่เมื่อรันการเปลี่ยนชื่อมันจะบอกว่าไม่มีคำสั่งอยู่ ไปคิด
adamlogan

2

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

rename --counter-format 000001 --lower-case --keep-extension --expr='$_ = "$N" if @EXT' *

1

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

นับจำนวน

@Gnutt พฤติกรรมที่คุณต้องการสามารถทำได้โดยการพิมพ์ดังต่อไปนี้:

./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r

หากตัวเลือก-rนั้นถูกปล่อยออกมาการทำซ้ำจะถูกจำลองเท่านั้น (น่าจะเป็นประโยชน์สำหรับการทดสอบ)

otion L อธิบายความยาวของจำนวนเป้าหมาย (ซึ่งจะเต็มไปด้วยเลขศูนย์นำ) ก็ยังเป็นไปได้ที่จะเพิ่มคำนำหน้า / -p <prefix> -s <suffix>ต่อท้ายด้วยตัวเลือก

ในกรณีที่มีคนต้องการจัดเรียงไฟล์เป็นตัวเลขก่อนที่พวกเขาจะได้รับหมายเลขเพียงลบ-o modtimeตัวเลือก



1

ให้เราสมมติว่าเรามีไฟล์เหล่านี้ในไดเรกทอรีโดยเรียงตามลำดับการสร้างรายการแรกสุด:

a.jpg
b.JPG
c.jpeg
d.tar.gz
e

จากนั้นls -1crส่งออกรายการด้านบนทั้งหมด จากนั้นคุณสามารถใช้rename:

ls -1cr | xargs rename -n 's/^[^\.]*(\..*)?$/our $i; sprintf("%03d$1", $i++)/e'

ซึ่งผลลัพธ์

rename(a.jpg, 000.jpg)
rename(b.JPG, 001.JPG)
rename(c.jpeg, 002.jpeg)
rename(d.tar.gz, 003.tar.gz)
Use of uninitialized value $1 in concatenation (.) or string at (eval 4) line 1.
rename(e, 004)

คำเตือน” การใช้ค่าเริ่มต้น […]” จะปรากฏขึ้นสำหรับไฟล์ที่ไม่มีนามสกุล; คุณสามารถละเว้นได้

ลบออก-nจากrenameคำสั่งเพื่อใช้การเปลี่ยนชื่อจริง

คำตอบนี้เป็นแรงบันดาลใจจากคำตอบของลุคของเมษายน 2014 มันจะเพิกเฉยต่อข้อกำหนดของ Gnutt ในการกำหนดจำนวนของเลขศูนย์นำขึ้นอยู่กับจำนวนไฟล์ทั้งหมด


นี่เป็นคำตอบที่มีประโยชน์ที่สุดสำหรับฉันส่วนใหญ่เป็นเพราะฉันต้องการแห้ง op ก่อนที่มันจะวิ่งและเพราะฉันสามารถปรับแต่งคำสั่งโดยเปลี่ยนเป็นls -1tUเวลาสร้าง มันจำเป็นต้องrenameติดตั้งซึ่งฉันไม่ได้มี
antonyh

1

อีกครั้งโดยใช้วิธีการของ Pero ด้วยการปรับเปลี่ยนเพียงเล็กน้อยเพราะfindจะข้ามทรีไดเรกทอรีในรายการสั่งซื้อจะถูกเก็บไว้ในรายการไดเรกทอรี นี้จะ (ส่วนใหญ่) จะสอดคล้องกันจากการเรียกใช้เพื่อทำงานบนเครื่องเดียวกันและเป็นหลักจะเป็น "ลำดับการสร้างไฟล์ / ไดเรกทอรี" ถ้าไม่มีการลบ

อย่างไรก็ตามในบางกรณีคุณจำเป็นต้องได้รับการสั่งซื้อทางตรรกะพูดตามชื่อซึ่งใช้ในตัวอย่างนี้

find -name '*.jpg' | sort -n | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command 

3
ห้ามใช้สิ่งนี้ การเปลี่ยนเส้นทางไปสู่การทุบตีเช่นนี้เป็นความเสี่ยงด้านความปลอดภัยขนาดใหญ่ เกิดอะไรขึ้นถ้าหนึ่งในชื่อไฟล์เป็นของแบบฟอร์มblahblah; rm -r * blahblah.jpg?
xhienne

1

จัดเรียงตามเวลา จำกัด เฉพาะ jpg นำเลขศูนย์และชื่อฐาน (ในกรณีที่คุณต้องการ)

ls -t *.jpg | cat -n |                                           \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done

(ทั้งหมดในบรรทัดเดียวไม่มี\)


ในรูปแบบที่ยิ่งใหญ่ของสิ่งต่าง ๆ คำตอบมากมายในหน้านี้น่ากลัวดังนั้นบางทีนี่อาจไม่สมควรได้รับ downvote ฉันลังเลที่จะอัปเกรดสิ่งใดก็ตามที่ใช้lsในสคริปต์
tripleee

ฉันบันทึกคำตอบนี้จากด้านลบราวกับว่าเปราะบางมันใช้ได้กับกรณีการใช้งานเฉพาะที่ฉันมี
วิลล์

1
ls -1tr | rename -vn 's/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e'

เปลี่ยนชื่อ -vn - ลบnสำหรับโหมดทดสอบปิด

{$ i = 1;} - ควบคุมหมายเลขเริ่มต้น

"% 04d.jpg" - การควบคุมนับศูนย์04และตั้งค่าส่วนขยายเอาท์พุท. jpg


การถอนคำตอบนี้เนื่องจากใช้การเปลี่ยนชื่อดั้งเดิมเท่านั้น กรณีการใช้งานของฉันคือการแทนที่สองหลักแรกของไฟล์โดยตัวเลขเริ่มต้นที่ 01:rename -v -n 's/../our $i;if(!$i){$i=1;} sprintf("%02d", $i++)/e' *
ต่ำสุด

1

สำหรับฉันการรวมกันของคำตอบนี้ทำงานได้อย่างสมบูรณ์แบบ:

ls -v | gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | bash
  • ls -v ช่วยในการสั่งซื้อ 1 10 9 ในการแก้ไข: 1 9 10 เพื่อหลีกเลี่ยงปัญหาส่วนขยายชื่อไฟล์ด้วย jpg JPG jpeg
  • gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }'สร้างใหม่ด้วยอักขระ 4 ตัวและเลขศูนย์นำหน้า โดยการหลีกเลี่ยง mv ฉันจะไม่พยายามเขียนทับสิ่งที่มีอยู่แล้วโดยบังเอิญโดยมีหมายเลขเดียวกันโดยไม่ตั้งใจ
  • bash รัน

ระวังสิ่งที่ @xhienne พูดการวางเนื้อหาที่ไม่รู้จักเพื่อทุบตีมีความเสี่ยงด้านความปลอดภัย แต่นี่ไม่ใช่กรณีสำหรับฉันเนื่องจากฉันใช้รูปภาพที่สแกน


0

คุณยังสามารถใช้ls

ls *.JPG| awk 'BEGIN{ a=0 }{ printf "mv %s gopro_%04d.jpg\n", $0, a++ }' | bash

5
ดูmywiki.wooledge.org/ParsingLsและคำอธิบายเกี่ยวกับช่องโหว่ด้านความปลอดภัยในโซลูชันอื่นที่มีช่องโหว่เช่นเดียวกัน
Charles Duffy

1
ห้ามใช้สิ่งนี้ การเปลี่ยนเส้นทางไปสู่การทุบตีเช่นนี้เป็นความเสี่ยงด้านความปลอดภัยขนาดใหญ่ เกิดอะไรขึ้นถ้าหนึ่งในชื่อไฟล์เป็นของแบบฟอร์มblahblah; rm -r * blahblah.JPG?
xhienne

0

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

สคริปต์นี้จะเปลี่ยนชื่อไฟล์ตัวเลขที่มีอยู่ก่อน:

#!/usr/bin/perl

use strict;
use warnings;

use File::Temp qw/tempfile/;

my $dir = $ARGV[0]
    or die "Please specify directory as first argument";

opendir(my $dh, $dir) or die "can't opendir $dir: $!";

# First rename any files that are already numeric
while (my @files = grep { /^[0-9]+(\..*)?$/ } readdir($dh))
{
    for my $old (@files) {
        my $ext = $old =~ /(\.[^.]+)$/ ? $1 : '';
        my ($fh, $new) = tempfile(DIR => $dir, SUFFIX => $ext);
        close $fh;
        rename "$dir/$old", $new;
    }
}

rewinddir $dh;
my $i;
while (my $file = readdir($dh))
{
    next if $file =~ /\A\.\.?\z/;
    my $ext = $file =~ /(\.[^.]+)$/ ? $1 : '';
    rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext); 
}

0

oneliner นี้แสดงรายการไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันเรียงลำดับตามการสร้างเวลาในลำดับย้อนกลับ (หมายถึงไฟล์ที่เก่าที่สุดอยู่ที่จุดเริ่มต้น) และเปลี่ยนชื่อโดยอัตโนมัติด้วยศูนย์ต่อท้ายตามจำนวนไฟล์ที่ต้องการ นามสกุลไฟล์จะถูกเก็บไว้

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

ระวังว่าถ้าคุณมีการชนกันของชื่อไฟล์คุณกำลังสูญเสียไฟล์ ดังนั้นก่อนเปลี่ยนชื่อเป็นสิ่งที่แปลกชอบtemp001.jpgแล้วดำเนินการเป็นชื่อไฟล์สุดท้ายของคุณ

DIGITS=$(ls | wc -l | xargs | wc -c | xargs); ls -tcr | cat -n | while read n f; do mv "$f" "$(printf "%0${DIGITS}d" $n).${f##*.}"; done

1
การวิ่งlsไม่ใช่ครั้งเดียว แต่ดูเหมือนว่าสองครั้งจะดีกว่า แต่ฉันไม่ได้ศึกษาในเชิงลึก
tripleee

1. ถ้าฉันเสนอผู้จองผ่านออนไลน์โดยเจตนาคุณจะเปลี่ยนมันทำไมในภายหลัง ผู้ใช้หลายคนอย่างฉันชอบคัดลอกวาง oneliner เพื่อให้งานเสร็จสมบูรณ์ สำหรับผู้อื่นที่ต้องการคัดลอกทีละบรรทัดมีคำตอบอื่น ๆ ในหัวข้อนี้ 2. คำถามเดิมคือ "จำนวนศูนย์นำขึ้นอยู่กับจำนวนไฟล์ทั้งหมด" และดำเนินการในตอนแรกlsดังนั้นจึงจำเป็นต้องมีสองข้อ 3. คำสั่งดังกล่าวเป็นหนึ่งนัดและไม่ได้รวมอยู่ในสคริปต์ดังนั้นจึงมีเหตุผลว่าทำไมผู้คนถึงนิยมใช้งานแบบตอร์ปิโดหนึ่งเดียว
Flavio Aiello

1
ขออภัยไม่ทราบว่าคุณคิดว่าสำคัญ สำหรับฉันความสามารถในการอ่านโค๊ดสำคัญกว่าความสามารถในการคัดลอก / วางเป็นบรรทัดเดียว ฉันไม่ได้พบสภาพแวดล้อมที่ทุบตีจะมีปัญหากับการวางซึ่งครอบคลุมหลายบรรทัด แต่ฉันอาจจะมองเห็นบางสิ่งบางอย่าง
tripleee

0

นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน
ฉันได้ใช้คำสั่งเปลี่ยนชื่อเพื่อที่ว่าถ้าไฟล์ใดมีช่องว่างในชื่อของมันแล้วคำสั่งmvไม่สับสนระหว่างช่องว่างและไฟล์จริง

ที่นี่ฉันแทนที่ช่องว่าง '' ในชื่อไฟล์ด้วย '_' สำหรับไฟล์ jpg ทั้งหมด
#! / bin / ทุบตี
เปลี่ยนชื่อ 'y / / _ /' * jpg #replacing เว้นวรรคด้วย _
ให้ x = 0;
สำหรับฉันใน * .jpg; ทำ
    ให้ x = (x + 1)
    mv $ i $ x.jpg
เสร็จแล้ว

ติดตั้งเปลี่ยนชื่อบน linux (Ubuntu), "sudo apt install rename"
rishang bhavsar

0

ทุกวันนี้มีตัวเลือกหลังจากคุณเลือกหลายไฟล์เพื่อเปลี่ยนชื่อ (ฉันเห็นในตัวจัดการไฟล์ thunar)

  1. เลือกหลายไฟล์
  2. ตรวจสอบตัวเลือก
  3. เลือกเปลี่ยนชื่อ

พรอมต์มาพร้อมกับไฟล์ทั้งหมดใน dir นั้นโดยเฉพาะเพียงตรวจสอบกับส่วนหมวดหมู่


-1

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

ls -trU *.mp4| awk 'BEGIN{ a=0 }{ printf "mv %s lecture_%03d.mp4\n", $0, a++ }' | bash

1
ห้ามใช้สิ่งนี้ การเปลี่ยนเส้นทางไปสู่การทุบตีเช่นนี้เป็นความเสี่ยงด้านความปลอดภัยขนาดใหญ่ เกิดอะไรขึ้นถ้าหนึ่งในชื่อไฟล์เป็นของแบบฟอร์มblahblah; rm -r * blahblah.mp4?
xhienne

-1

นี่คือวิธีแก้ไขปัญหาอื่นด้วยคำสั่ง "เปลี่ยนชื่อ":

find -name 'access.log.*.gz' | sort -Vr | rename 's/(\d+)/$1+1/ge'

หากต้องการคืนค่าศูนย์นำหน้า:rename 's/(\d+)/sprintf("%04d",$1)+1/ge'
Camille Goudeseune

ใช้งานไม่ได้ตามที่คาดไว้สำหรับโฟลเดอร์ที่มีไฟล์ที่มีชื่อดังนี้: DSC_3451.JPG, DSC_3452.JPG เป็นต้นค้นหา -name '* .JPG' | sort -Vr | เปลี่ยนชื่อ 's / (\ d +) / $ 1 + 1 / ge' ไม่ได้แก้ไขอะไรเลย
Tiberiu C.

-2

คำตอบของ Pero ทำให้ฉันมาที่นี่ :)

ฉันต้องการเปลี่ยนชื่อไฟล์เมื่อเทียบกับเวลาเนื่องจากผู้ดูภาพไม่ได้แสดงรูปภาพตามลำดับเวลา

ls -tr *.jpg | # list jpegs relative to time
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command

2
ห้ามใช้สิ่งนี้ การเปลี่ยนเส้นทางไปสู่การทุบตีเช่นนี้เป็นความเสี่ยงด้านความปลอดภัยขนาดใหญ่ เกิดอะไรขึ้นถ้าหนึ่งในชื่อไฟล์เป็นของแบบฟอร์มblahblah; rm -r * blahblah.jpg? เป็นเพียงตัวอย่างที่รุนแรง
xhienne


-3

ในการเปลี่ยนหมายเลข 6000 ไฟล์ในโฟลเดอร์เดียวคุณสามารถใช้ตัวเลือก 'เปลี่ยนชื่อ' ของโปรแกรม ACDsee

สำหรับการกำหนดคำนำหน้าให้ใช้รูปแบบนี้: ####"*"

จากนั้นตั้งค่าหมายเลขเริ่มต้นแล้วกดเปลี่ยนชื่อจากนั้นโปรแกรมจะเปลี่ยนชื่อไฟล์ทั้งหมด 6,000 ไฟล์ด้วยหมายเลขเรียงลำดับ


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