Tập tin mv Linux với tên dài


19

Trong Linux, đôi khi tôi đổi tên các tệp như thế này:

mv dir1/dir2/dir3/file.txt  dir1/dir2/dir3/file.txt.old

Lưu ý rằng tôi muốn chỉ đổi tên tệp, không di chuyển nó sang thư mục khác.

Có lệnh nào cho phép tôi thực hiện phiên bản tốc ký của lệnh đó không? Tôi đang nghĩ một cái gì đó như:

mv dir1/dir2/dir3/file.txt  file.txt.old

hoặc thậm chí có thể là một cái gì đó như (chỉ thêm vào tên):

mv dir1/dir2/dir3/file.txt  {}.old

Mục tiêu của tôi là không phải xác định lại đường dẫn hoàn chỉnh.

Tôi biết những "ví dụ" mà tôi đã viết không hoạt động, nhưng đó chỉ là một ý tưởng về những gì tôi muốn thực hiện.

Tôi không muốn phải cd vào thư mục.


8
Tại sao bạn không thay đổi thư mục? Nó là nhanh chóng và giải quyết vấn đề của bạn.
Michael Hampton

Tôi đang giao dịch với nhiều thư mục con từ cùng địa điểm này, sẽ chậm hơn nếu tôi phải quay lại thư mục phụ huynh này mỗi lần
santiago arizti

3
Không ai nói bạn phải đổi sang một số thư mục khác, chỉ có thư mục bạn muốn.
Michael Hampton

Lưu ý rằng (cd dir1/dir2/dir3 && exec mv file.txt{,.old})có hiệu suất tương tự như mã mà không có quy trình con, bởi vì exectránh fork()ing trong khi gọi lệnh bên ngoài, do đó bạn có chính xác một ngã ba.
Charles Duffy

Câu trả lời:


45

cho một tập tin thử

mv dir1/dir2/dir3/file.{txt,txt.old}

nơi X{a,b}cấu trúc mở rộng tới Xa Xb, bạn có thể có bản xem trước bằng cách sử dụng

echo dir1/dir2/dir3/file.{txt,txt.old}

để xem nếu nó phù hợp với nhu cầu của bạn.

chú thích:

  1. cho nhiều tập tin

    mv dir1/dir2/dir3/file{1,2,3}.{txt,txt.old}
    

không có khả năng mở rộng đến những gì bạn muốn. (điều này sẽ mở rộng thành hỗn hợp của file.txt file1.txt.old file2.txt ...)

  1. {txt,txt.old}có thể được rút gọn {,.old}theo nhận xét

  2. nếu tên thư mục không rõ ràng, ký tự đại diện có thể được sử dụng.

    mv *1/*2/d*/*.{,old}
    

để sử dụng nhiều tập tin rename

rename -n s/txt/old.txt/ dir1/dir2/dir3/file*.txt 

thả -nđể có sự đổi tên hiệu quả.


1
thật tuyệt, tôi không biết cách mở rộng này! cảm ơn bạn
santiago arizti

14
Sẽ mv dir1/dir2/dir3/file.txt{,.old}không làm việc, và thậm chí còn ngắn hơn?
Josh

3
@Josh Có nó hoạt động hoàn hảo và yêu cầu ít tổ hợp phím hơn. Tôi sử dụng cấu trúc này rất thường xuyên.
rlf

2
thật buồn cười khi bạn có thể sử dụng trình bao Linux trong nhiều năm và vẫn luôn tìm thấy các thủ thuật mới
santiago arizti

Tôi đoán tất cả những "mánh khóe" đó sẽ rõ ràng hơn nếu tôi được đào tạo chính thức về ngôn ngữ bash, nhưng tôi chỉ học đủ để hòa đồng.
santiago arizti

6

Lệnh renameđổi tên tất cả các tập tin phù hợp. Mục đích chính của nó là đổi tên nhiều tệp, nhưng nếu biểu thức Perl chỉ khớp với một tệp, thì nó sẽ chỉ đổi tên tệp này. Để biết chi tiết và phân phối cú pháp cụ thể xin vui lòng đọc manpage : man rename.

Ví dụ sử dụng: đổi tên "/path/file.txt" thành "/path/file.txt.old":

rename 's/file.txt/file.txt.old/g' /path/file.txt

Ký hiệu ngắn hơn (nhờ shalomb):

rename 's/$/.old/' /path/file.txt
rename '$_.=".old"' /path/file.txt

Để sử dụng chạy khô rename -n.

Các ví dụ và chi tiết khác có thể được tìm thấy tại https://thepcspy.com/read/bulk-rename-files-in-ub Ubuntu /


Thật tuyệt, tôi biết về lệnh đổi tên, chỉ cần không bao giờ biết tất cả những gì nó có thể làm, cảm ơn bạn!
santiago arizti

6
Thật không may, các bản phân phối Linux khác nhau có các renamelệnh khác nhau với hành vi hoàn toàn khác nhau.
kasperd

1
Đối với nhiệm vụ đặc biệt này là đổi tên bằng cách thêm .oldvào tên tệp, có thể thuận tiện hơn một chút để thực hiện một rename 's/$/.old/' /path/to/file.txthoặcrename '$_.=".old"' /path/to/file.txt
shalomb

@Fabian - Tôi không phải là kẻ ngốc, chỉ nhắm đến "bàn tay ngắn nhất" cho những gì dường như là một thành ngữ thường được sử dụng mà OP đang tìm kiếm :)
shalomb

4

Đối với trường hợp một lần, nếu tôi muốn không thay đổi thư mục hiện tại của mình, tôi có thể chỉ sử dụng một vỏ con:

(cd dir1/dir2/dir3/ && mv file.txt file.txt.old)

Vì bạn cdở trong vỏ phụ, bạn đã không thay đổi thư mục của mình trong vỏ thực tế


4
Sử dụng nhanh hơn và an toàn hơn && exec mv- theo cách đó bạn không cố gắng thực hiện việc đổi tên nếu cdthất bại và exectiêu thụ phần phụ, do đó tránh bị phạt hiệu suất.
Charles Duffy

Đồng ý với trường && hợp một lần, như tôi đã nói, tôi sẽ không lo lắng về chi phí của vỏ phụ (giữ cho nó đơn giản: có thể dễ dàng nhớ cách thực hiện IMO quan trọng hơn)
Adam

Tôi lập luận rằng nếu bạn chỉ nhớ một cách, việc nhớ cách hiệu quả sẽ giúp đảm bảo bạn không đi theo con đường không hiệu quả trong trường hợp vấn đề.
Charles Duffy

4

Tôi thích giải pháp sử dụng mở rộng {} của archemar, bởi vì bạn có thể sử dụng nó khi bạn đã bắt đầu dòng lệnh của mình. Dưới đây là một số khả năng khác để hoàn thiện:

F="dir1/dir2/dir3/file.txt" ; mv "$F" "$F.old"

(trích dẫn chỉ cần thiết nếu bạn có khoảng trắng hoặc các ký tự ngắt từ khác trong tên)

mymv() {
    mv "$1/$2" "$1/$3"
}

mymv dir1/dir2/dir3 file.txt file.txt.old
mymv dir5/dir6/dir7 file.txt file.txt.old

Ghi chú:

  • Đây là cú pháp bash, bạn có thể đang sử dụng shell khác
  • mymv có thể là bất kỳ chuỗi hợp lý nào, tôi đã sử dụng mymv cho "di chuyển của tôi".
  • Định nghĩa hàm có thể được đặt trong .bash_profile của bạn

Một số khác:

cd dir1/dir2/dir3 ; mv file.txt file.txt.old ; cd -

nhưng

(cd dir1/dir2/dir3/ && exec mv file.txt file.txt.old)

(từ @Adam và @CharlesDuffy) được cho là tốt hơn trong trường hợp cd thất bại.


1
Đừng sử dụng mmv, đã có một chương trình được đặt tên theo cách này.
glglgl

1
@glglgl Xong :)
Law29

2

Nếu bạn muốn nhập thư mục con để rút ngắn mvlệnh, nhưng muốn quay lại thư mục hiện tại sau đó, có hai cách để làm điều đó. Một là đặt cdmvtrong một subshell (như đã được đề xuất).

Khác là sử dụng pushdpopdthay đổi thư mục:

pushd dir1/dir2/dir3/; mv file.txt file.txt.old; popd

Các pushdlệnh giống như cd, ngoại trừ nó lần đầu tiên đẩy tên của thư mục hiện lên một chồng. popdxóa tên trên khỏi ngăn xếp và thay đổi thư mục đó.


pushdpopdlà các tiện ích mở rộng dành cho sử dụng tương tác - POSIX liệt kê rõ ràng chúng là "kết quả không xác định" và trình bao được xây dựng để chạy tập lệnh (ví dụ: trên môi trường nhúng tối thiểu) không cần hỗ trợ chúng.
Charles Duffy

2

Tôi sẽ làm

cd dir1/dir2/dir3/
mv file.txt file.txt.old
cd ~- # go to the most recent directory

0

Giải pháp liên quan đến: mv something{.txt,.txt.old}đang sử dụng một "bashism". Nếu bạn muốn một cách di động hơn, sử dụng các thao tác biến phổ biến:

# rename all files "file*.txt" of directory /dir1/dir2/dir3 into file*.txt.old:
for f in dir1/dir2/dir3/file*.txt ; do
  mv "$f" "${f/.txt/.txt.old}"  # note there are no terminating "/"
done


# "${var/A/B}" is the content of var with the first occurence of "A" replaced by "B"

2
Xem pubs.opengroup.org/onlinepub/009695399/utilities/ vào để biết thông số kỹ thuật POSIX thích hợp - ${var/text/replacement}là một chính bashism.
Charles Duffy

@CharlesDuffy oh ... Bạn làm tôi buồn :(
Olivier Dulac
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.