Je ne vais pas faire du "code golf" (le plus court gagne) C'est plus comme un "code basket".
Parce que vos besoins sont un peu complexes, je vous conseille d'utiliser le plus accordable option.
Nous lançons avec
Find (root directory) -type f | perl count21
Count21 est un fichier qui contient du perl.
while (<>) { # read each line of input into variable $_
chomp $_; # Removing newline at end of line, if exists. It does.
local $/ = undef; # Input will ignore newlines and slurp in entire file
open (my $IN, "<", $_); # immune to < > ' " tab etc. in filename
my $text = <$IN>; # read entire file
chomp $text; # remove last newline if exists, so files with or
# without trailing newlines are the same.
$lc = ( $text =~ tr/\n// ) + 1; # tr/\n// counts newline characters.
# $text =~ says apply this operation to $text.
# The value of this operation is char count.
# Add 1 so we count the last line.
# This count will be wrong on 0-line files,
# but that's outside of problem scope.
if (21 >= $lc) { # if $lc <= 21 (Putting var first is bad luck)
print $_, "\n"; # print filename, and a newline
} # endif
} # end while(<>)
S'embêter avec tout ce perl et éviter tous les raccourcis semble super stupide . La raison de le faire est vous pouvez faire face beaucoup plus facilement aux rides inattendues comme le problème "certaines lignes ne se terminent pas par une nouvelle ligne", facilement résolu avec un chomp et un +1 ici.
Cela élimine également le problème que vous auriez avec le passage de listes de fichiers en shell, comme les noms de fichiers avec espaces , ", ', |, onglet et autres clés à molette. Malheureusement, la tuyauterie de Find ne supportera pas nouvelle ligne dans un nom de fichier, mais le module Perl File::Find le fera.
Il est également facile d'ajouter encore plus de choses : par exemple, si vous ne voulez que les fichiers avec "diddle", ajoutez
next if not ( $text =~ /diddle/i );