tìm tập tin không khớp với danh sách các mẫu tên tệp


7

Tôi thấy mình cần tìm và xác định các tệp không liên quan (trong số khoảng 900K tệp trên ổ 2T). Có rất nhiều tệp mà tôi muốn giữ và tôi có các mẫu tên tệp cho các tệp tốt đã biết này. Điều tôi muốn là xác định vị trí các tệp không phù hợp với bất kỳ mẫu nào.

Làm cách nào để tìm các tệp không khớp với danh sách các mẫu tên tệp?

Tôi có thể chạy findđể lấy danh sách tất cả các tệp và tôi có thể sử dụng grep -vkết quả bằng cách sử dụng danh sách các mẫu được lưu trữ trong tệp. Đây có phải là phương pháp chính tắc, hoặc bạn có một cách ngắn gọn để tìm các tệp không phù hợp này?


Làm rõ - dựa trên các câu trả lời, đây là một ít thông tin hơn. Tôi hy vọng sẽ có nhiều mẫu (> 20, có thể> 100), tôi muốn lưu trữ chúng trong một tệp và chắc chắn muốn một cách dễ dàng để thêm mẫu mới. Tôi muốn tránh trực tiếp chỉnh sửa một danh sách lớn các tham số tìm kiếm (dễ vỡ), nhưng việc xây dựng danh sách đó có thể hoạt động.


Câu trả lời Perl giả định rằng bạn có các mẫu được lưu trữ trong một tệp riêng biệt và đọc từ đó. Nó cố gắng khớp các tên tệp với các mẫu theo nghĩa đen hoặc bằng cách diễn giải các mẫu đó là các khối.
Joseph R.

Tôi đã chỉnh sửa câu trả lời của mình để giải quyết yêu cầu "mẫu trong tệp"
Warren Young

Câu trả lời:


3

Vì bạn đề cập đến Perl ...

#!/usr/bin/perl

use strict;
use warnings;
use File::Find qw{find};

my %patterns;
while (<>) {
  chomp;
  $patterns{$_}++;
}

die "No pattern supplied\n" unless keys %patterns;

find( 
    sub{
           my $matches_a_pattern=0;
           for my $pattern (keys %patterns){
               my $glob_pattern = $pattern;
               for($glob_pattern){
                   s/\./\\./g;
                   s/\*/.*/g;
                   s/\?/./g;
               }
               $matches_a_pattern++ if ( /\Q$pattern\E/ or /$glob_pattern/);
           }

           print "$File::Find::name\n" unless $matches_a_pattern;
     }
    , '.' )

Gọi đây là

/path/to/my/script file_with_patterns

Thay thế .ở cuối với ngọn cây bạn muốn đi bộ.


19

find(1)đủ mạnh để làm những gì bạn cần Chỉ cần thu thập tất cả các tên tuân thủ vào một biểu thức bằng dấu ngoặc đơn, sau đó phủ định nó để hiển thị tên tệp không tuân thủ . Ví dụ, để hiển thị tất cả các file không có tên *.txt, *.bz2hoặc *.zip:

$ find . \! \( -name \*.txt -o -name \*.bz2 -o -name \*.zip \)

Bạn có thể sử dụng -notthay vì \!với GNU và BSD find. Nó không tuân thủ POSIX, nhưng nó không yêu cầu một lối thoát để ngăn vỏ giải thích nó.

Để xây dựng biểu thức từ các mẫu trong một tệp, đó là một vấn đề nhỏ của kịch bản lệnh shell:

#!/bin/sh
set --
while IFS= read -r pattern
do
    set -- "$@" -o "$pattern"
done < .fnpatterns
if [ $# -ne 0 ]; then
  shift
  set -- -not \( "$@" \)
fi
find . "$@"

Điều này mong đợi một tệp trong thư mục hiện tại được gọi .fnpatternsvới một mẫu trên mỗi dòng. Để bắt chước một lớp lót ở trên, nó cần phải chứa:

*.txt
*.bz2
*.zip

Lưu ý rằng tập lệnh shell thoát các *ký tự trong các mẫu cho bạn.

Bạn có thể làm điều này phức tạp tùy ý. Một vài ý tưởng:

  • Thêm -type fvào findlệnh để nó chỉ hiển thị các tập tin bình thường, không phải thư mục.

  • Truyền tên tệp mẫu vào làm đối số thay vì mong đợi nó ở một vị trí cố định

  • Giữ tập tin mẫu nó ở đâu, nhưng thêm -o -name .fnpatternsvào xây dựng-up findlệnh vì vậy nó không hiển thị trong kết quả. (Điều này cũng sẽ tránh được việc shifthack "ăn" khách hàng tiềm năng -otrong biểu thức dựng sẵn.)

  • Thêm hành động cho findlệnh thông qua -exechoặc tương tự.

  • Cho phép dòng trống hoặc nhận xét trong tệp mẫu


set --nghĩa là gì
Roberto

@Roberto: Người đầu tiên sẽ xóa tất cả các thông số vị trí của kịch bản: $1, $2, vv gắn thêm thứ hai -o $patternvào danh sách tham số, vì vậy mà ở phần cuối của vòng lặp chúng tôi có tất cả các mẫu từ các .fnpatternstập tin như thể truyền cho các kịch bản trong bán - finddạng biểu thức. Chúng tôi đã có thêm -omột mặt trận, vì vậy chúng tôi shifttắt nó, sau đó bọc toàn bộ điều trong một phủ định với set --lệnh thứ ba . Bây giờ danh sách tham số vị trí của chúng tôi chứa một findbiểu thức hợp lệ mà chúng tôi chuyển qua sử dụng "$@".
Warren Young
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.