เปลี่ยนชื่อไฟล์จำนวนมาก


25

ฉันมีไฟล์จำนวนหนึ่ง:

10.3.100.179_01_20161018_230014_5335.jpg
10.3.100.179_01_20161018_231514_0814.jpg
10.3.100.179_01_20161018_233014_5706.jpg
10.3.100.179_01_20161018_234514_0896.jpg
10.3.100.179_01_20161018_230114_5395.jpg
10.3.100.179_01_20161018_231614_1145.jpg
10.3.100.179_01_20161018_233114_6047.jpg
10.3.100.179_01_20161018_234614_0547.jpg
10.3.100.179_01_20161018_230114_5492.jpg
10.3.100.179_01_20161018_231614_1264.jpg
10.3.100.179_01_20161018_233114_6146.jpg
10.3.100.179_01_20161018_234614_0658.jpg
10.3.100.179_01_20161018_230214_5630.jpg
10.3.100.179_01_20161018_231714_7135.jpg

ฉันต้องการเปลี่ยนชื่อด้วยรูปแบบนี้:

10.4.100.135_01_20161013131108389_TIMING.jpg
10.4.100.135_01_20161013131111390_TIMING.jpg
10.4.100.135_01_20161013131114401_TIMING.jpg
10.4.100.135_01_20161013131117431_TIMING.jpg
10.4.100.135_01_20161013131120418_TIMING.jpg
10.4.100.135_01_20161013131123461_TIMING.jpg
10.4.100.135_01_20161013131126511_TIMING.jpg

จะต้องมีการลบในการประทับเวลาและเพิ่ม__TIMING



5
โปรดใช้ตัวอย่างที่สอดคล้องกันในคำถามของคุณ ดูเหมือนว่าคุณต้องการแทนที่ด้วย10.3.100.179 10.4.100.135นั่นคือสิ่งที่คุณต้องการหรือคุณเพียงต้องการลบ_TIMINGและ_จากเวลา
terdon

3
เวลาที่ดีในการเตือนผู้คนว่ามีมาตรฐาน iso8601 สำหรับวันที่ (ใช้งานได้ทั้งชื่อไฟล์และรายการบันทึก) ^^ ดังนั้นคุณควรพิจารณาการเปลี่ยนชื่อเป็น YYYY-MM-DDThh: mm: ss.mmm (เช่นเดิม : ไฟล์แรกของคุณจะกลายเป็น: 10.4.100.135_01_2016-10-13T13:11:08.389_TIMING.jpg(และ "TIMING" สามารถถูกลบออกได้เนื่องจากมันดูเหมือนวันที่และชั่วโมง (และมิลลิวินาที) โดยเฉพาะอย่างยิ่งเมื่อมาตรฐานแพร่หลายมากขึ้น T เป็นส่วนหนึ่งของมาตรฐานและฉัน เติบโตขึ้นมาชอบมัน (และนำมันออกมาทำลายมาตรฐาน ^^)
โอลิเวียร์ดุแล

@OlivierDulac ฉันจะไม่แนะนำให้ใช้:ในชื่อไฟล์ ฉันเชื่อว่า Windows ไม่รองรับ
จัสติน

@ จัสตินจุดดี มาตรฐานแนะนำให้วางชื่อไฟล์ ฉันให้เวอร์ชันในไฟล์
Olivier Dulac

คำตอบ:


38

ติดตั้งrenameutilsและใช้งานqmvกับโปรแกรมแก้ไขข้อความที่คุณชื่นชอบ

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

ฉันมักจะทำ:

$ qmv -f do

เพื่อให้มันแสดงเพียงชื่อคอลัมน์เดียว (ทำ: ปลายทางเท่านั้น) นี่คือลักษณะ:

qmw

หากคุณรวมเข้ากับเคอร์เซอร์หลายตัวของ SublimeText, Atom หรือ Visual Studio Code มันทำให้เป็นเครื่องมือที่ดีและทรงพลังสำหรับการเปลี่ยนชื่อจำนวนมาก EDITOR="atom -w" qmv -f doยกตัวอย่างเช่นสำหรับอะตอมคุณจะทำอย่างไร


1
ยินดีต้อนรับสู่ถาม Ubuntu! มันเจ๋งมาก!
αғsнιη

ลงนามเพียงเพื่อ +! มัน. ;)
J. Allan

2
ว้าวเครื่องมือที่ดีและภาพเคลื่อนไหว GIF ที่ดี คำตอบแรกที่ดียินดีต้อนรับ! :)
ผู้บัญชาการไบต์

1
ขอบคุณ @KasiyA สำหรับการสร้างภาพและขอบคุณทุกคนสำหรับความคิดเห็นเชิงบวก
ateijelo

1
@kasperd ใช่มันจะเตือนว่าแผนเปลี่ยนชื่อมีข้อผิดพลาดและเปิดคอนโซลแบบโต้ตอบที่สามารถดำเนินการเพิ่มเติมได้
ateijelo

27

ใช้rename...

rename -n 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *

ด้วย-nสิ่งนี้จะแสดงสิ่งที่มันจะทำโดยไม่ทำการเปลี่ยนแปลงใด ๆ :

rename(10.3.100.179_01_20161018_230014_5335.jpg, 10.3.100.179_01_201610182300145335_TIMING.jpg)
rename(10.3.100.179_01_20161018_231514_0814.jpg, 10.3.100.179_01_201610182315140814_TIMING.jpg)
rename(10.3.100.179_01_20161018_233014_5706.jpg, 10.3.100.179_01_201610182330145706_TIMING.jpg)
rename(10.3.100.179_01_20161018_234514_0896.jpg, 10.3.100.179_01_201610182345140896_TIMING.jpg)

ถ้ามันดูถูกต้องลบ -n

$ rename 's/^([0-9]+\.[0-9]\.[0-9]+\.[0-9]+_[0-9]+_)([0-9]+)_([0-9]+)_([0-9]+)\.jpg/$1$2$3$4_TIMING\.jpg/' *
$ ls
10.3.100.179_01_201610182300145335_TIMING.jpg  10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_201610182315140814_TIMING.jpg  10.3.100.179_01_201610182345140896_TIMING.jpg

อธิบาย ...

  • s/something/something_else/ ค้นหาและแทนที่
  • ^ จุดเริ่มต้นของชื่อ (การยึด)
  • [0-9] หมายเลขใดก็ได้
  • + อักขระนำหน้าอย่างน้อยหนึ่งตัว
  • \.ตามตัวอักษร.(ไม่มี\สิ่งนี้ตรงกับตัวละครใด ๆ )
  • () เพื่อรักษาส่วนนี้
  • $1$2$3$3 ย้อนกลับการอ้างอิงถึงสิ่งที่ตรงกันก่อนหน้านี้และเก็บไว้ด้วย ()

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


2
บน distros บางคำสั่งนี้สามารถใช้ได้เป็นprename(P สำหรับ Perl เพราะหาเรื่องแรกคือการแสดงออก Perl)
ปีเตอร์ Cordes

12

mmv สามารถทำได้ดังต่อไปนี้:

mmv '*_*_*_*_*.jpg' '#1_#2_#3#4#5_TIMING.jpg'

10.3.100.179_01_20161018_230014_5335.jpg 10.3.100.179_01_201610182300145335_TIMING.jpg

# 1, # 2, # 3, ... กำลังอ้างอิงแต่ละรายการถึงการจับคู่ '*' ที่นี่

มันสั้นกว่าด้วย:

mmv '*_*_*.jpg' '#1#2#3_TIMING.jpg'

9

renameวิธีอื่น:

$ rename -n 's/(.*)_(.*)_(.*)\./$1$2$3_TIMING./' *
10.3.100.179_01_20161018_230014_5335.jpg -> 10.3.100.179_01_201610182300145335_TIMING.jpg
10.3.100.179_01_20161018_230114_5395.jpg -> 10.3.100.179_01_201610182301145395_TIMING.jpg
10.3.100.179_01_20161018_230114_5492.jpg -> 10.3.100.179_01_201610182301145492_TIMING.jpg
10.3.100.179_01_20161018_230214_5630.jpg -> 10.3.100.179_01_201610182302145630_TIMING.jpg
10.3.100.179_01_20161018_231514_0814.jpg -> 10.3.100.179_01_201610182315140814_TIMING.jpg
10.3.100.179_01_20161018_231614_1145.jpg -> 10.3.100.179_01_201610182316141145_TIMING.jpg
10.3.100.179_01_20161018_231614_1264.jpg -> 10.3.100.179_01_201610182316141264_TIMING.jpg
10.3.100.179_01_20161018_231714_7135.jpg -> 10.3.100.179_01_201610182317147135_TIMING.jpg
10.3.100.179_01_20161018_233014_5706.jpg -> 10.3.100.179_01_201610182330145706_TIMING.jpg
10.3.100.179_01_20161018_233114_6047.jpg -> 10.3.100.179_01_201610182331146047_TIMING.jpg
10.3.100.179_01_20161018_233114_6146.jpg -> 10.3.100.179_01_201610182331146146_TIMING.jpg
10.3.100.179_01_20161018_234514_0896.jpg -> 10.3.100.179_01_201610182345140896_TIMING.jpg
10.3.100.179_01_20161018_234614_0547.jpg -> 10.3.100.179_01_201610182346140547_TIMING.jpg
10.3.100.179_01_20161018_234614_0658.jpg -> 10.3.100.179_01_201610182346140658_TIMING.jpg

-nหากที่ดูเหมือนว่าจะทำงานตามที่คุณต้องการที่จะลบ


5

คุณยังสามารถใช้สิ่งต่อไปนี้ ก่อนอื่นให้ทำการสำรองไฟล์และลองทำสิ่งนี้:

find . -name "*.jpg" -type f -print0| while read -d $'\0' file
do
    #extension="${file##*.}"
    newfilename=$(echo "${file%.*}" | sed 's/\(.*\)_\(.*\)_/\1\2/')
    mv "$file" "$newfilename""_TIMING.jpg"
done

sed 's/\(.*\)_\(.*\)_/\1\2/')ลบ_อักขระในการประทับเวลา

ตัวอย่างเช่น:

user@host$ ls -lart
total 8
drwxrwxr-x 6 user user 4096 Oct 21 10:21 ..
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230014_5335.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231514_0814.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233014_5706.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234514_0896.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230114_5395.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231614_1145.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233114_6047.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234614_0547.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230114_5492.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231614_1264.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_233114_6146.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_234614_0658.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_230214_5630.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_20161018_231714_7135.jpg
drwxrwxr-x 2 user user 4096 Oct 21 10:30 .

user@host$ find . -name "*.jpg" -type f -print0 | while read -d $'\0' file
> do
>  newfilename=$(echo "${file%.*}" | sed 's/\(.*\)_\(.*\)_/\1\2/')
>  mv $file $newfilename"_TIMING.jpg"
> done

10:35:20 t $ ls -lart
total 8
drwxrwxr-x 6 user user 4096 Oct 21 10:21 ..
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182300145335_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182315140814_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182330145706_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182345140896_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182301145395_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182316141145_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182331146047_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182346140547_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182301145492_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182316141264_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182331146146_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182346140658_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182302145630_TIMING.jpg
-rw-rw-r-- 1 user user    0 Oct 21 10:30 10.3.100.179_01_201610182317147135_TIMING.jpg
drwxrwxr-x 2 user user 4096 Oct 21 10:35 .

1
นี่คือทางออกที่ดีที่สุด แน่นอนว่า soultion ของ Zanna นั้นสมบูรณ์แบบสำหรับไฟล์สองสามไฟล์ แต่เนื่องจากเชลล์ทำการวนรอบโดยเชลล์การแก้ปัญหาอาจล้มเหลวในไฟล์จำนวนมาก (สตริงคำสั่งยาวเกินไป)
rexkogitans

@rexkogitans: หากคุณใช้ระบบ Linux ที่ทันสมัย ​​(เช่น Ubuntu ทุกรุ่น) ขีดจำกัดความยาวบรรทัดคำสั่งคือหลายเมกะไบต์ และหากเป็นปัญหาคุณสามารถใช้find -maxdepth 1 -exec rename ... {} +ในการแบตช์รายการของไดเรกทอรีปัจจุบันไปยังบรรทัดคำสั่งของการเปลี่ยนชื่อ (เพิ่ม-name *.jpgหรืออะไรก็ได้ที่คุณต้องการ) ที่จะดำเนินการได้เร็วกว่าเชลล์วนที่ forks + execs sedและmvสำหรับทุกชื่อไฟล์แทนการเปลี่ยนระบบการเรียก (คุณสามารถกำจัดการsedใช้สิ่ง regex ในตัวของทุบตี แต่ฟอร์กmvยังคงช้า ish.)
Peter Cordes

2

คุณอาจเสร็จสิ้นแล้ว แต่นี่เป็นbashวิธีแก้ปัญหาทั้งหมด (ง่าย) :
"ง่าย ... วิธีทุบตี" oxymoron หรือไม่?

#!/bin/bash

#loop through all files ending in .jpg
for f in *.jpg;
do

    #cut out everything to the timestamp
    firsthalf=${f%_*_*_*}

    #get from the timestamp on
    lasthalf=${f#*_*_}

    #remove (all) underscores from timestamp
    #note the 2 forward slashes...
    lasthalf=${lasthalf//_/}

    #get our extension
    ext=${lasthalf##*.}

    #now we can remove the extension
    lasthalf=${lasthalf%.*}

    #rename the file
    #change `mv` to `echo` if you want to do a trial run first...
    mv "$f" "${firsthalf}_${lasthalf}_TIMING.${ext}"

done;

PS:ตรรกะในลูปได้รับการทดสอบด้วยชื่อไฟล์ตัวอย่างของคุณ มันผ่านไปแล้ว


1
อาจดีกว่าที่จะใช้ regex ทุบตีกับ[[ $f ~= (.*)_(.*)_(.*)_(.*)\.jpg ]]; newname=${BASH_REMATCH[1]${BASH_REMATCH:2:4}TIMING.jpgหรืออะไร (ยังไม่ได้ทดสอบทั้งหมดและอาจผิด แต่ความคิดทั่วไปคือกลุ่มการดักจับเข้าไปในอาร์เรย์ BASH_REMATCH)
Peter Cordes

@PeterCordes: นั่นเป็นประเด็นที่ดี! ฉันไม่เคยใช้ ( bash) จับกลุ่มและซื่อสัตย์อย่างสมบูรณ์ทุบตีไม่ใช่ภาษาแรกที่ฉันลองใช้ (ฉันคิดว่าbashเป็นภาษาที่น่าเกลียด) ถึงกระนั้นมันก็เป็นทางออกที่ดีและสอนให้ฉันมีความรุ่งโรจน์
J. Allan

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

@PeterCordes: ฉันได้รับคะแนนของคุณแม้ว่าฉันไม่คิดว่ารหัสนั้น "น่าเกลียด" อาจไม่ใช่โซลูชัน 2 บรรทัดที่คุณให้ แต่ก็ไม่ยากที่จะอ่านเท่าที่ฉันกังวล รวมทั้งมีการแสดงความคิดเห็นที่ดี ...
เจ Allan

ฉันกำลังพูดถึงรหัสทุบตีเสร็จโดยทั่วไปน่าเกลียด (หรืออย่างน้อยอ่านยาก) จริงๆแล้วมันไม่ได้น่าเกลียดจริง ๆ เพียงแค่ค่อนข้างงอใจ (เช่นการผ่าน args โดยการอ้างอิงในการทุบตีโดยการส่งชื่อตัวแปรและมี callee ใช้printf -v "$3" ...ในการตั้งค่าตัวแปรที่มีชื่ออยู่$3) แยกบรรทัดคำสั่งทั้งหมดแล้ววางกลับ กันค่อนข้างยากที่จะติดตาม / debug อย่างน้อยฉันก็พบว่าเป็นอย่างนั้นในขณะที่พยายามทำความสะอาด / แก้ไขข้อบกพร่อง ดูรหัสบน GitHub
Peter Cordes

1

หากคุณสามารถใช้ GUI ผมจะแนะนำให้pyRenamer

มันมีอยู่ในการกระจายส่วนใหญ่ fi ใน Ubuntu:

sudo apt-get install pyrenamer

มันสามารถทำทุกอย่างที่คุณต้องการและอื่น ๆ

  • มันสามารถใช้รูปแบบเพิ่มหรือระงับข้อความ
  • มันสามารถเข้าถึงข้อมูล EXIF ​​หากเปลี่ยนชื่อรูปภาพเพื่อให้คุณสามารถสร้างรูปแบบตามวันที่ / เวลา ฯลฯ ...
  • สามารถใช้ข้อมูลเมตาบางส่วนได้หากเปลี่ยนชื่อไฟล์เพลง
  • นอกจากนี้ยังมีตัวอย่างซึ่งสามารถป้องกันข้อผิดพลาดบางอย่างยากที่จะเปลี่ยนกลับ

ถึงผู้ลงคะแนนเสียง ... สนใจที่จะอธิบายว่าทำไม OP ไม่ได้ระบุว่า GUI เป็นตัวเลือกหรือไม่ ฉันเห็นคำตอบส่วนใหญ่ไปที่ทางคอนโซล / สคริปต์ แต่ผู้ใช้หลายคนจะประทับใจกับโซลูชัน GUI หรือบางที pyRenamer มีข้อบกพร่องบางอย่างฉันไม่ทราบ ไม่ว่าในกรณีใดฉันต้องการทราบสาเหตุของการลงคะแนน
jrierab

ฉันขอแนะนำ Thunar Bulk Renamer สำหรับวิธีการโต้ตอบกับ GUI ได้เร็วขึ้นด้วย
Tony Martin

@TonyMartin นี่ควรเป็นความเห็นภายใต้คำถามนี้ไม่มีอะไรจะทำอย่างไรกับคำตอบ
Sergiy Kolodyazhnyy

0

นี่คือตัว ดิบfind+ xargs+ sed+ mvoneliner (ความรักของคุณ):

find . -name "*.jpg" -print0 | sort -z | xargs -0 sh -c 'for filename; do mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g"); done' sh

คำอธิบาย:

  • find . -name "*.jpg" | sort | xargs sh -c <command> sh : แสดงรายการ JPEG ทั้งหมดในไดเรกทอรีปัจจุบันจากนั้นเรียกใช้คำสั่งเชลล์สำหรับแต่ละรายการ (การเรียงลำดับเป็นทางเลือกแน่นอน แต่ควรรักษาความสะอาดให้น้อยลงหากคุณเข้าสู่ระบบที่ใดที่หนึ่ง)

  • -print0, -z, -0: มันเป็นนิสัยที่ดีในรายการแยกต่างหากกับไบนารี0เมื่อ tokenizing ชื่อไฟล์เพื่อหลีกเลี่ยงปัญหาที่มีในที่ตรงกลางสีขาวช่องว่าง (ไม่ใช่กรณีของคุณแม้ว่า)

  • mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g");(เครื่องหมายในsed's regex ไม่ได้ช่วยให้การอ่านของมัน แต่มันเป็นง่าย) เปลี่ยนชื่อแต่ละไฟล์โดยการเปลี่ยนลำดับขีด-separeted 8 + 6 + 4 หลักที่มีการเรียงต่อกันต่อเนื่องกันของพวกเขาบวกนี้_TIMINGสิ่ง ( \iเป็น backreference ไปi- กลุ่มที่ regex)


Refs: Xargs - man sed

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