Tránh liệt kê các tệp kết thúc bằng ~ (tệp sao lưu)


20

Yêu cầu của tôi là liệt kê tất cả các tệp trong một thư mục, ngoại trừ các tệp kết thúc bằng một ~(tệp sao lưu).

Tôi đã cố gắng sử dụng lệnh:

ls -l | grep -v ~    

Tôi nhận được kết quả này:

asdasad
asdasad~
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell1.sh~
testshell2.sh
testshell2.sh~
testtwo.txt
testtwo.txt~
test.txt
test.txt~

Tôi chỉ muốn nhận các tệp này:

asdasad
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell2.sh
testtwo.txt
test.txt

Có vẻ như bạn đang cố gắng tránh liệt kê các tệp kết thúc bằng a ~. Những tập tin này là tập tin sao lưu được tạo ra một số trình soạn thảo văn bản của tôi.
ctrl-alt-delor

Bạn đang sử dụng hệ điều hành nào: đó có phải là Gnu / Linux (như Debian, Ubuntu, Redhat, Centos, Fedora, Suse, Mint, Arch, lỗi) không?
ctrl-alt-delor

2
Lưu ý rằng tệp bạn muốn bỏ qua dường như là tệp sao lưu Emacs. Thật dễ dàng để thay đổi hành vi của Emacs để nó lưu các bản sao lưu trong một thư mục tập trung và không phải ở khắp mọi nơi; xem emacs.stackexchange.com/questions/33/ Cách
Kilian Foth

Tôi xin lỗi có nghĩa là nhưng tôi không tin bạn; ls -l(chữ ell) sẽ bao gồm các quyền, liên kết, chủ sở hữu, kích thước và thời gian sửa đổi cho mỗi tệp được liệt kê. Những gì sẽ tạo ra đầu ra mà bạn hiển thị là ls -1(chữ số một) và trên nhiều hệ thống -1là cần thiết để tạo đầu ra một cột trên thiết bị đầu cuối , nhưng khi lsđược dẫn (như ở đây grep) hoặc chuyển hướng, -1thì không cần thiết, nó đã là một cột .
dave_thndry_085

@ dave_thndry_085 Tôi đã cắt bớt tất cả văn bản và chỉ tên tệp ở đây .. Bởi vì tôi cảm thấy điều đó không liên quan. Và đây cũng là một hệ thống sản xuất (không phải hệ thống của riêng tôi). Vì vậy, tôi không muốn liệt kê tên người dùng, chi tiết và rò rỉ chúng.
tò mò_one

Câu trả lời:


49
ls -l | grep -v ~

Lý do điều này không hoạt động là vì dấu ngã được mở rộng vào thư mục nhà của bạn, vì vậy grepkhông bao giờ thấy dấu ngã theo nghĩa đen. (Xem ví dụ: hướng dẫn của Bash về Mở rộng Tilde .) Bạn cần trích dẫn nó để ngăn chặn việc mở rộng, tức là

ls -l | grep -v "~"

Tất nhiên, điều này vẫn sẽ xóa bất kỳ dòng đầu ra nào có dấu ngã ở bất cứ đâu, ngay cả ở giữa tên tệp hoặc ở nơi khác trong lsđầu ra (mặc dù có thể nó không xuất hiện trong tên người dùng, ngày hoặc như vậy). Nếu bạn thực sự chỉ muốn bỏ qua các tệp kết thúc bằng dấu ngã, bạn có thể sử dụng

ls -l | grep -v "~$"

48

Việc triển khai GNU ls(được tìm thấy trên hầu hết các hệ thống Linux) có một tùy chọn cho việc đó: -BBỏ qua các bản sao lưu:

ls --ignore-backups

24

Nếu bạn đang sử dụng bash, hãy đảm bảo extglobđược bật:

shopt -s extglob

Sau đó, bạn có thể sử dụng:

ls -d -- !(*~)
  • -d không hiển thị nội dung thư mục
  • !(*~) tất cả các tệp ngoại trừ những tệp kết thúc bằng ~

Trên zsh, bạn có thể thực hiện tương tự với kshglobtùy chọn hoặc sử dụng các khối lượng mở rộng của riêng nó:

setopt extended_glob
ls -d -- ^*~

Vì hậu tố để loại trừ chỉ dài một ký tự, bạn cũng có thể ghép các tên tệp trong đó ký tự cuối cùng không phải là dấu ngã (điều này cũng hoạt động mà không có extglob)

ls -d -- *[^~]

Nhưng ý tưởng chung là sử dụng ls --ignore-backups.


12

Điều này sẽ giúp:

ls -l | grep -v '~'  

Lý do: ~ char được thay thế bởi thư mục chính của bạn trước khi lệnh được thực thi. Thử

echo ~

echo '~'

6

Như đã đề cập trong các câu trả lời khác, lý do bạn có thể gặp vấn đề là vì bạn đã không trích dẫn hoặc thoát khỏi dấu ngã.

Đối với một trường hợp sử dụng cụ thể, tôi đã sử dụng mở rộng tên tệp shell để làm điều gì đó tương tự. Tôi đã sử dụng nó từ khoảng năm 2003, điều đó có nghĩa là nó đã hoạt động trên rất nhiều triển khai hệ vỏ trên các loại hệ thống khác nhau. (ở đây tôi cũng sử dụng -Cvì tôi muốn một màn hình đẹp trong các cột được sắp xếp)

ls -C *[!~]

(một hạn chế với việc sử dụng mở rộng tên tệp shell tất nhiên là một thư mục có số lượng tệp (không sao lưu) rất lớn sẽ khiến việc mở rộng vượt quá kích thước danh sách đối số có sẵn, mặc dù trên hầu hết các hệ thống hiện đại, giới hạn này khá cao, thường là 250KB trở lên, đôi khi nhiều hơn nữa)


1

ls | grep -v '~$'là giải pháp nhanh chóng. Nó sử dụng ls để liệt kê tất cả các tệp (không bị ẩn), sau đó sử dụng grep với -v(khớp ngược, nghĩa là loại trừ) để loại trừ tất cả các dòng có dấu ngã ( ~) ở cuối ( $).

TUY NHIÊN, nếu bạn có BẤT K file tệp nào có tên như cái gì đó1, cái gì đó2, thì đó là một chỉ báo nặng mùi mà bạn có một quy trình công việc tồi tệ, bạn nên sửa lỗi tại nguồn, không phải với các bản hack khó hiểu như sửa đổi cách thức hoạt động của ls.

Nếu bạn thấy mình đặt tên tệp với số phiên bản, như test1 và test2 hoặc testone và testtwo, thì điều bạn thực sự muốn là một hệ thống kiểm soát phiên bản, như thế nào git.

Điều này đặc biệt đúng trong trường hợp của bạn, nơi bạn có nhiều phiên bản của nhiều tệp và phiên bản dường như cần được phối hợp giữa tất cả các tệp.

Các hệ thống kiểm soát phiên bản cho phép bạn chủ yếu che một cửa sổ thời gian lên hệ thống tệp, do đó bạn chỉ nhìn thấy một testtệp, nhưng trong phần mềm (thông qua chương trình kiểm soát phiên bản), tất cả các phiên bản đều có sẵn để tìm kiếm, truy xuất, hoàn nguyên, so sánh với, v.v. .

Khi bạn đã thiết lập xong, bạn không còn cần các tệp sao lưu từ trình chỉnh sửa của mình, bởi vì kiểm soát phiên bản có lịch sử của các tệp kể từ khi bạn bắt đầu sử dụng nó, ngay cả khi bạn đã thực hiện một nghìn thay đổi kể từ đó. Bạn thậm chí có thể "phân nhánh" dòng thời gian lịch sử, thử một ý tưởng mới và quay ngược thời gian và sau đó chuyển tiếp để thử một ý tưởng khác, nếu bạn cần.


1

Mặc dù nhiều câu trả lời là đúng (tôi @Foonđặc biệt thích câu trả lời ), tôi lưu ý rằng việc lấy danh sách các tên có ls -lhơi khập khiễng vì nhiều lý do.

Công cụ thích hợp để tìm các tập tin là, không ngạc nhiên , find.

Một trong những điểm nổi bật của nó là nó có thể tự xử lý "logic lựa chọn":

$ find . -maxdepth 1 \( -type f -a \! -name '*~' \) -print

nghĩa đen là nói findvới:

  1. Tìm kiếm các tập tin trong thư mục hiện tại: .
  2. Chỉ tìm chúng ở cấp độ của thư mục đó, đó là, không tái diễn: -maxdepth 1
  3. Ở đó, tìm kiếm các thực thể, mà

    • loại tập tin: -type f
    • và: -a
    • có tên không kết thúc bằng ~: ! -name *~ (trong đó !phủ định chỉ thị sau khớp với tên tệp, -name *~).

    (Để làm cho toàn bộ kết quả khớp về loại và tên xuất hiện dưới dạng một đơn vị logic, nó được ngoặc đơn với ()).

  4. In tên của mỗi tập tin được tìm thấy : -print.

Bạn cần bảo vệ một số ký tự đặc biệt đối với hệ vỏ khỏi bị giải thích bởi vỏ và đó là lý do tại sao dấu ngoặc đơn và tiếng nổ !, được thoát dấu gạch chéo ngược và mẫu tên *~, được bao quanh bằng dấu ngoặc đơn.

Các findlệnh có một mini-ngôn ngữ rất mạnh mẽ thông qua việc sử dụng các tùy chọn của nó. Ví dụ, nó có thể được yêu cầu xử lý đệ quy toàn bộ cây hệ thống tập tin (hoặc cây) nhưng bỏ qua các thư mục nhất định trong khi quét. Có thể khớp với một số thuộc tính của các tập tin, chẳng hạn như thời gian tạo hoặc sửa đổi hoặc kích thước của bất cứ thứ gì.

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.