Cách đổi tên nhiều tệp trong một thư mục cùng một lúc


12

Tôi có thư mục nói /var/tmp/abccó 4 tệp:

12345-ram-3e3r5-io9490-89adu9.csv
45434-dam-qwe35-to9490-43adu9.csv
11234-cam-yy3r5-ro9490-85adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv

Tôi muốn đổi tên tất cả các tệp CSV (tìm tất cả các tệp và đổi tên chúng) theo cách ngắn nhất có thể (có thể là một lớp lót) theo cách này:

XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

Câu trả lời:


15

rename -n 's/(\w+)/XXXXX/' *.csv

Loại bỏ -nkhi hạnh phúc.


2
Đối với một phiên bản phù hợp của rename. Tôi cho rằng đây là của Larry Wall rename, từ renamegói trong Debian và phái sinh (và IIRC prenametrên các hệ thống thuyết phục RedHat). Một công cụ rất hữu ích.
xenoid

2
perl-renametrong arch linux
lesmana

1
@SHawarden, tôi đã thử thực thi lệnh và đọc phần có liên quan của trang man để hiểu mẫu thay thế, nhưng khi thêm verbosecờ, nó không tạo ra gì và không thực hiện thay đổi tên tệp, mặc dù đường dẫn hiện tại có tập tin có tên tương tự 12345_foo.csv. Tôi có phải thực hiện bất kỳ nhiệm vụ bổ sung nào để nó hoạt động không (hiện tại trên Fedora 30)? Đó là một cách tiếp cận sạch hơn vòng lặp. Cảm ơn trước!
danieldeveloper001

3
@ danieldeveloper001 Bạn đã sử dụng renamehay prename? Xem bình luận của tôi ở trên. man {the command}liệt kê các tác giả ở cuối
xenoid

2
Điều này chỉ hoạt động trên các hệ thống có nguồn gốc Debian. Các hệ thống có nguồn gốc từ Fedora có một renamelệnh hoàn toàn khác ; xem unix.stackexchange.com/a/238862/135943
tự đại diện

11

Thử:

for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done

Làm thế nào nó hoạt động:

  • for f in *.csv; do

    Điều này bắt đầu một vòng lặp trên tất cả *.csvcác tập tin.

  • mv -i -- "$f" "XXXXX-${f#*-}"

    Điều này đổi tên các tệp như bạn muốn, hỏi tương tác trước khi ghi đè bất kỳ tệp nào.

  • done

    Điều này đánh dấu sự kết thúc của vòng lặp.

Thí dụ:

$ ls -1
11234-cam-yy3r5-ro9490-85adu9.csv
12345-ram-3e3r5-io9490-89adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv
45434-dam-qwe35-to9490-43adu9.csv
$ for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done
$ ls -1
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

4

Tôi thích thử thách nhỏ mà bạn đã đăng, vì vậy đây là giải pháp của tôi. Tôi giả sử rằng tất cả các tệp của bạn bắt đầu bằng 5 ký tự số, vì vậy sử dụng lệnh cắt để thay thế các tệp số ban đầu bằng "XXXXX".

Dưới đây, các tập tin trước lệnh.

-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 11111_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 12345_baz_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml

Dưới đây, một lệnh lót.

for src in *.csv; do dst=XXXXX$(echo $src| cut -c6-); mv $src $dst; done;

Dưới đây, các tập tin sau lệnh.

-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 XXXXX_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 XXXXX_baz_file.csv

Có phải đó là những gì bạn đang tìm kiếm? :)

Người giới thiệu:

Vòng lặp thông qua đầu ra lệnh trong bash

Chất nền trong bash


2
Bash có thể thực hiện kiểu thao tác chuỗi này, không cần rẽ nhánh một quy trình mới cho mỗi quy trình, xin vui lòng trả lời khác về cách thức.
chx

1
@chx, đã thấy các câu trả lời khác và có được một chút kiến ​​thức từ nó, nhưng cảm ơn vì đã chỉ ra chúng. Bạn vui lòng giải thích chi tiết no need to fork a new process for each?
danieldeveloper001

3
cutlà một nhị phân ( /usr/bin/cut) riêng biệt và việc chạy nó tiêu tốn nhiều tài nguyên hơn so với sử dụng shell được xây dựng.
chx

2
Tôi thấy, nó thực sự quan trọng nếu ý định đổi tên rất nhiều tập tin. Cảm ơn bạn đã làm rõ!
danieldeveloper001

1

không có dĩa:

ls | perl -lne '$suf=substr($_,6); rename $_, "XXXXX-$suf"'

Khi bạn sử dụng vòng lặp shell, các mvdĩa một lần cho mỗi tệp. Perl củarenameLệnh thì không.

(Lệnh đổi tên của Perl có một số hạn chế, nhưng trong trường hợp cụ thể này, những hạn chế đó không được áp dụng.)

Đối với renamelệnh được hiển thị trước đó, có, nó hoạt động, nhưng sau đó bạn có tất cả sự nhầm lẫn giữa hai loại đổi tên khác nhau và vân vân. Nếu bạn có đúng, tuyệt vời, nhưng nếu không, điều này cũng hoạt động.

Nếu bạn không có lệnh perl-rename và không thể cài đặt nó, bạn có thể làm điều này:

ls | perl -lne '$old=$_; s/(\w+)/XXXXX/; rename $old, $_'

Như bạn có thể thấy, điều này sử dụng cùng một sự thay thế được hiển thị trong câu trả lời hàng đầu. Tất nhiên perl-đổi tên có chuông và còi khác (câu trả lời đầu đã đề cập, -nđã có, sau đó có -0, -fvà vân vân), và nhiều trong số họ bạn cần, bạn càng nên cài đặt thay vì cán của riêng bạn theo cách này .


Việc thực hiện thông thường của một đường ống sẽ có dĩa.
muru

Ý tôi là, "sẽ không rẽ nhánh một lần cho mỗi tệp được đổi tên", không giống như shell, trong đó "mv" forks / usr / bin / mv hoặc bất cứ điều gì. Điều này là do lệnh "đổi tên" là lệnh nội bộ perl gọi trực tiếp tên đổi tên () trong libc. Tất nhiên nó có một số hạn chế, nhưng trong ví dụ cụ thể này, những hạn chế đó không được áp dụng.
sitaram

1
Điều đó cũng đúng với renamelệnh ( câu trả lời hàng đầu , cũng sử dụng Perl), vì vậy có lẽ bạn nên thêm một chút giải thích hơn là chỉ đơn giản là "không có dĩa" cho câu trả lời.
muru
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.