Đổi tên tập tin hàng loạt


25

Tôi có một số tệp:

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

Tôi muốn đổi tên với định dạng này:

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

Nó cần phải loại bỏ _dấu thời gian và thêm _TIMING.



5
Vui lòng sử dụng các ví dụ nhất quán trong câu hỏi của bạn. Có vẻ như bạn muốn thay thế 10.3.100.179bằng 10.4.100.135. Đó có phải là những gì bạn muốn hoặc bạn chỉ muốn loại bỏ _TIMING_từ thời gian?
terdon

3
Một thời điểm tốt để nhắc nhở mọi người rằng có một tiêu chuẩn iso8601 cho các ngày (hoạt động cả cho tên tệp VÀ cho các mục nhật ký) ^^ Vì vậy, có lẽ bạn nên xem xét lại việc đổi tên để trở thành: YYYY-MM-DDThh: mm: ss.mmm (ví dụ : tệp đầu tiên của bạn sẽ trở thành: 10.4.100.135_01_2016-10-13T13:11:08.389_TIMING.jpg(và "THỜI GIAN" thậm chí có thể bị xóa, vì bây giờ nó trông rõ ràng giống như ngày và giờ (và mili giây), đặc biệt là khi tiêu chuẩn trở nên phổ biến hơn. T là một phần của tiêu chuẩn và tôi lớn lên để thích nó (và lấy nó ra phá vỡ tiêu chuẩn ^^)
Olivier Dulac

@OlivierDulac Tôi không khuyên bạn nên sử dụng :tên tệp. Tôi tin rằng Windows không hỗ trợ nó.
Justin

@Justin điểm tốt. tiêu chuẩn khuyến nghị bỏ nó cho tên tập tin. Tôi đã đưa ra phiên bản trong tệp
Olivier Dulac

Câu trả lời:


38

Cài đặt renameutilsvà sử dụng qmvvới trình soạn thảo văn bản yêu thích của bạn.

qmvtải tất cả các tên trong trình chỉnh sửa của bạn và khi bạn lưu và đóng nó sẽ áp dụng các thay đổi của bạn cho các tệp thực tế. Nếu các thay đổi không nhất quán (ví dụ: hai tệp có cùng tên), nó sẽ hủy bỏ mà không chạm vào bất cứ thứ gì. Nó cũng xử lý đổi tên chính xác.

Tôi thường làm:

$ qmv -f do

sao cho nó chỉ hiển thị một cột tên (do: chỉ đích). Đây là vẻ ngoài của nó:

xe máy

Nếu bạn kết hợp nó với nhiều con trỏ của SublimeText, Atom hoặc Visual Studio Code, nó sẽ tạo ra một công cụ rất hay và mạnh mẽ để đổi tên hàng loạt. Ví dụ, đối với Atom, bạn sẽ làm EDITOR="atom -w" qmv -f do.


1
Chào mừng bạn đến hỏiUbfox! Điều này thật tuyệt!
αsнι

Đã ký nó chỉ để +! nó ;)
J. Allan

2
Wow, công cụ đẹp và hoạt hình GIF đẹp. Câu trả lời đầu tiên tuyệt vời, được chào đón! :)
Chỉ huy Byte

1
Cảm ơn @KasiyA đã nội tuyến hình ảnh và cảm ơn mọi người khác vì những bình luận tích cực.
ateijelo

1
@kasperd Có, nó sẽ cảnh báo rằng kế hoạch đổi tên có lỗi và mở bảng điều khiển tương tác nơi có thể thực hiện các hành động tiếp theo.
ateijelo

27

Sử dụng 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/' *

Với -nđiều này sẽ tạo ra những gì nó sẽ làm mà không thực hiện bất kỳ thay đổi nào:

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ếu nó trông đúng, loại bỏ -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

Giải thích ...

  • s/something/something_else/ tìm kiếm và thay thế
  • ^ bắt đầu của tên (neo)
  • [0-9] bất kỳ số nào
  • + một hoặc nhiều nhân vật đi trước
  • \.nghĩa đen .(không có \cái này phù hợp với bất kỳ nhân vật nào)
  • () để giữ phần này
  • $1$2$3$3 tham chiếu lại những thứ phù hợp trước đó và được giữ lại với ()

Lưu ý: *ở cuối lệnh khớp với tất cả các tệp hiển thị trong thư mục hiện tại. Sử dụng một quả cầu phù hợp hơn nếu cần thiết.


2
Trên một số distro, lệnh này có sẵn dưới dạng prename(p cho perl, vì đối số đầu tiên là biểu thức perl)
Peter Cordes

12

mmv có thể làm như sau:

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, ... đang giới thiệu từng người với '*' phù hợp tại đây.

Nó thậm chí còn ngắn hơn với:

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

9

Một renamecách tiếp cận khác :

$ 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ếu điều đó dường như hoạt động như bạn muốn, hãy loại bỏ -n.


5

Bạn cũng có thể sử dụng như sau. Trước tiên hãy sao lưu các tệp của bạn và thử điều này:

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/')xóa các _ký tự trong dấu thời gian.

Ví dụ:

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
đây là giải pháp tốt nhất Tất nhiên, linh hồn của Zanna là hoàn hảo cho một vài tệp, nhưng vì việc tạo khối được thực hiện bởi trình bao, giải pháp của họ có thể thất bại trên một số lượng lớn tệp (chuỗi lệnh quá dài).
rexkogitans

@rexkogitans: Nếu bạn đang sử dụng hệ thống Linux hiện đại (tức là bất kỳ phiên bản Ubuntu nào), giới hạn về độ dài dòng lệnh là nhiều megabyte. Và nếu đó là một vấn đề, bạn có thể sử dụng find -maxdepth 1 -exec rename ... {} +để bó danh sách thư mục hiện tại vào dòng lệnh đổi tên. (thêm -name *.jpghoặc bất cứ điều gì bạn muốn). Điều đó sẽ thực thi nhanh hơn nhiều so với một vòng lặp shell mà thực hiện + thực thi sedmvcho mỗi tên tệp, thay vì chỉ một cuộc gọi hệ thống đổi tên. (Bạn có thể thoát khỏi việc sedsử dụng công cụ regex tích hợp sẵn của bash, nhưng việc chuyển đổi mvvẫn còn chậm.)
Peter Cordes

2

Có lẽ bạn đã hoàn thành, nhưng đây là một bashgiải pháp (đơn giản) tất cả :
"Giải pháp bash đơn giản" có phải là oxymoron không?

#!/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: Logic trong vòng lặp đã được kiểm tra với một trong các tên tệp ví dụ của bạn. Nó đã qua.


1
Có lẽ tốt hơn để sử dụng một regex bash với [[ $f ~= (.*)_(.*)_(.*)_(.*)\.jpg ]]; newname=${BASH_REMATCH[1]${BASH_REMATCH:2:4}TIMING.jpghoặc một cái gì đó. (hoàn toàn chưa được kiểm tra và có thể sai, nhưng ý tưởng chung là các nhóm bắt giữ đi vào mảng BASH_REMATCH.)
Peter Cordes

@PeterCordes: Đó là một điểm tốt! Tôi chưa bao giờ sử dụng ( bash) các nhóm bắt giữ, và thành thật mà nói, bash không phải là ngôn ngữ đầu tiên mà tôi thử chúng. (Tôi nghĩ bashlà một ngôn ngữ xấu xí.) Tuy nhiên, đó là một giải pháp tốt và nó đã dạy cho tôi một cái gì đó rất kudos.
J. Allan

Yup, lý do chính để thực hiện nhiều xử lý văn bản trong bash thuần là khi viết các hàm hoàn thành tab phải nhanh. Nó mang đến một ý nghĩa hoàn toàn mới cho cụm từ "mã xấu xí" ...
Peter Cordes

@PeterCordes: Tôi hiểu ý của bạn, mặc dù tôi không nghĩ rằng mã đó là "xấu xí". Nó có thể không phải là giải pháp 2 dòng bạn đưa ra, nhưng không khó để đọc xa như tôi quan tâm; cộng với đó là nhận xét tốt ...
J. Allan

Tôi đã nói về mã hoàn thành bash nói chung là xấu (hoặc ít nhất là khó đọc). Nó thực sự không xấu, chỉ hơi khó hiểu (ví dụ: chuyển args bằng ref trong bash được thực hiện bằng cách chuyển một tên biến và sử dụng callee printf -v "$3" ...để đặt biến có tên $3.) Tách toàn bộ dòng lệnh và đặt lại cùng nhau là khá khó để theo dõi / gỡ lỗi, ít nhất tôi đã tìm thấy nó theo cách đó trong khi cố gắng dọn sạch / sửa lỗi. Xem mã trên github
Peter Cordes

1

Nếu bạn có thể sử dụng GUI, tôi sẽ khuyên dùng pyRenamer .

Nó có mặt trong hầu hết các bản phân phối, fi trong Ubuntu:

sudo apt-get install pyrenamer

Nó có thể làm tất cả những gì bạn muốn và nhiều hơn nữa.

  • Nó có thể sử dụng các mẫu, thêm hoặc chặn văn bản.
  • Nó có thể truy cập vào dữ liệu EXIF ​​nếu đổi tên ảnh, do đó bạn có thể tạo các mẫu dựa trên ngày / giờ, v.v ...
  • Có thể sử dụng một số siêu dữ liệu nếu đổi tên tệp nhạc.
  • Hơn nữa, nó có một bản xem trước , có thể ngăn ngừa một số sai lầm khó hoàn nguyên.

Để downvoter ... Quan tâm giải thích tại sao? OP không chỉ định nếu GUI là một tùy chọn hay không. Tôi thấy hầu hết các câu trả lời đều thuộc về giao diện điều khiển / tập lệnh, nhưng nhiều người dùng sẽ đánh giá cao một giải pháp GUI. Hoặc có thể pyRenamer có một số lỗ hổng mà tôi không biết. Trong mọi trường hợp, tôi muốn biết lý do cho downvote.
jrierab

Tôi cũng có thể đề xuất Thunar Bulk Renamer cho cách tiếp cận GUI tương tác linh hoạt.
Tony Martin

@TonyMartin Điều này nên được bình luận dưới câu hỏi, điều này không liên quan gì đến câu trả lời
Sergiy Kolodyazhnyy

0

Đây là tích hợp find + xargs+ sed+ thô của bạnmv (oneliners tình yêu) oneliner:

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

Giải trình:

  • find . -name "*.jpg" | sort | xargs sh -c <command> sh : liệt kê tất cả các JPEG trong thư mục hiện tại, sau đó thực thi lệnh shell cho từng cái (tất nhiên việc sắp xếp là tùy chọn, nhưng hãy giữ mọi thứ sạch sẽ hơn một chút nếu bạn đang đăng nhập ở đâu đó)

  • -print0, -z,-0 : Đó là thói quen tốt để các mặt hàng riêng biệt với nhị phân 0khi tokenizing tên tập tin để tránh các vấn đề với in-the-middle trắng-không gian (không phải trường hợp của bạn mặc dù)

  • mv "$filename" $(echo "${filename}" | sed "s/\([0-9]\{8\}\)_\([0-9]\{6\}\)_\([0-9]\{4\}\)/\1\2\3_TIMING/g");: (Backslashes trong sed's regex không giúp dễ đọc của nó, nhưng nó đơn giản) đổi tên mỗi tập tin bằng cách thay thế chuỗi gạch-separeted của 8 + 6 + 4 chữ số với nối tiếp giáp của họ cộng này _TIMINGđiều ( \ilà một backreference đếni - nhóm regex thứ).


Tham khảo : Xargs - người đàn ông quyến rũ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.