Trừ 1 từ tất cả các tên tệp (đổi tên chúng) trong một thư mục.


17

Tôi có một thư mục chứa các tệp hình ảnh với tên như

image1.jpg 
image2.jpg 
image3.jpg
...

Thật không may, tên hình ảnh phải bằng không, vì vậy image1.jpgnên image0.jpg, image2.jpgnên image1.jpgvà vân vân.

Tôi có thể viết một tập lệnh để tạo các lệnh mv như thế này, đặt chúng vào tập lệnh shell và sau đó thực thi chúng -

mv image1.jpg image0.jpg
mv image2.jpg image1.jpg
mv image3.jpg image2.jpg
...

Nhưng tôi cho rằng có một cách gọn gàng hơn để làm điều đó trong Unix. Vậy đo la cai gi?


6
Đó thực sự là cách đơn giản nhất để làm điều đó, miễn là không có khoảng trống. ( for i in $(seq 0 100); do mv image$[i+1].jpg image$i.jpg; done)
Ricky Beam

5
Là thứ tự của hình ảnh quan trọng? Nếu không, chỉ cần đổi tên hình ảnh cuối cùng từ imageN.jpgđến image0.jpgvà bạn đã làm xong.
jnovacho

@jnovacho, khá thông minh! Nhưng có, thứ tự của hình ảnh là quan trọng.
Wes

Câu trả lời:


20

Đổi tên perl cũ tốt:

rename 's/(\d+)(\.jpg)/($1-1).$2/e' *

[Ghi chú]

Số hình ảnh phải lớn hơn 0.

Trong trường hợp hình ảnh lớn hơn 9 và không dẫn 0, hãy sử dụng $(ls -v1 *)để tránh bị che khuất. Được đề xuất bởi @arielf và được chú ý bởi @Graeme.

Khi nghi ngờ cũng sử dụng -vcho dài dòng và -nkhông hành động.


"E" chỉ ra điều gì?
Wes

3
'e' có nghĩa là đánh giá, phần thay thế sẽ được đánh giá. xem thêmperlreref

6
Các tập tin nên được chuyển theo thứ tự tăng dần để tránh bất kỳ ghi đè nào. Điều này sẽ chỉ hoạt động tốt nếu có ít hơn 10 tệp (hoặc nếu số có số 0 đứng đầu).
Graeme

Tôi đã nhận thấy điều này rồi, cũng không được có 0trong các nguồn.

2
thay thế *ở cuối `ls -v1 *`và bạn sẽ an toàn hơn từ việc ghi đè. Nó sẽ đi từ số thấp nhất đến cao nhất.
arielf

6

Bạn có thể dẫn các mvlệnh được tạo ra bash. Vì vậy, bạn không phải sao chép chúng trong một kịch bản và thực hiện điều đó. Xem:

command_that_generates_mv_commands | bash

Và tất cả mọi thứ sẽ được thực hiện được dẫn đến bash.


Đó không phải là gọn gàng hơn. :)Giải quyết vấn đề mặc dù, vì vậy +1.
JMCF125

5

Bạn có thể lặp lại trên đầu ra ls, cái này hoạt động cho ví dụ của bạn:

i=0 
for file in $(ls *.jpg | sort) ; do 
     mv $file $(echo $file | sed 's/[0-9]*.jpg$/'${i}'.jpg/')
     i=$((++i))
done

Bạn phải ở trên cùng một đường dẫn của tệp của bạn


1
Tốt hơn để sử dụng -ihoặc -nvới mv, nó sẽ ngăn chặn ghi đè trong các trường hợp cạnh.
Graeme

sẽ không sort -Vthể tốt hơn để thay thế?
user80551

sortsẽ không hoạt động, nó sẽ hiển thị image10.jpgtrước image1.jpgđó có thể là một vấn đề. Bạn cần sort -nk 1.8như trong câu trả lời của @ Graeme.
terdon

@ user80551, sort -Vlà một ý tưởng tốt, sẽ thêm nó vào câu trả lời của tôi. Mặc dù có thể có các trường hợp cạnh khác, chỉ nói chung là lời khuyên tốt để thêm các loại tùy chọn này với các câu hỏi như thế này trong trường hợp ai đó sao chép và cuối cùng gây ra một số thiệt hại.
Graeme

4

Sau đây dường như làm việc cho bất cứ điều gì phù hợp với mô hình imageNUMBER.jpg. Tôi đã đặt echotrước mvlệnh để hiển thị đầu tiên lệnh sẽ làm gì; để thực sự đổi tên, chỉ cần xóaecho

for i in `ls image*.jpg|sort -V` ; do 
    x=`echo $i|sed -e "s/image\(.*\).jpg/\1/"`
    y=$(( $x - 1 ))
    echo mv -i $i image$y.jpg
done

Trong dòng đầu tiên, ls image*.jpg|sort -Vsẽ làm cho các tệp JPG được liệt kê với số tăng dần trong tên tệp. Các x=dòng chiết xuất số lượng từ tên tập tin. Các y=dòng sau đó decrements số một. Tên tệp đầu vào và ysố sau đó được sử dụng trong mvlệnh, trong đó -icờ sẽ thông báo cho bạn trước khi ghi đè tệp.

Đối với thử nghiệm nhỏ của riêng tôi, điều này tạo ra đầu ra:

mv -i image1.jpg image0.jpg
mv -i image2.jpg image1.jpg
mv -i image123.jpg image122.jpg

Cá nhân, tôi khuyên bạn nên đổi tên thành một tên tệp khác, vì bây giờ thứ tự các tệp được xử lý có thể tạo ra sự khác biệt lớn.


1
Tốt hơn để sử dụng -ihoặc -nvới mv, nó sẽ ngăn chặn ghi đè trong các trường hợp cạnh.
Graeme

Gợi ý rất hay, tôi sẽ chỉnh sửa câu trả lời
brm

Trong macOS, bạn nên sử dụng sort -n, -Vtùy chọn không tồn tại.
Vincent Ngồi

4

Sử dụng perltập lệnh prenameđược liên kết để đổi tên trên các bản phát hành dựa trên Debian, cũng cần GNU find/ sort. Các tập tin được đặt theo thứ tự tăng dần để ngăn chặn bất kỳ ghi đè.

find . -regex '\./image[0-9]+\.jpg' -print0 | sort -zV |
  xargs -0 rename -n 's/(\d+)\.jpg$/@{[$1-1]}.jpg/'

Hủy bỏ -nmột khi bạn chắc chắn nó làm những gì bạn muốn. Sẽ cảnh báo về các tập tin đã tồn tại trước khi làm như vậy. Tuy nhiên, miễn là nó cho thấy các tệp được đổi tên theo thứ tự tăng dần, sẽ không có xung đột khi chạy thực sự.


Tập tin đã tồn tại vấn đề với cái này.
Wes

4

Với zsh:

autoload zmv # (in ~/.zshrc)
zmv -Qf -n 'image(<->).jpg(n)' 'image$(($1-1)).jpg'

(loại bỏ -nkhi hạnh phúc).

(n)là sắp xếp danh sách bằng số để image9.jpgđược đổi tên trước đó image10.jpg.

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.