파일 이름에서 가장 높은 번호의 줄을 출력합니다.

파일 이름에서 가장 높은 번호의 줄을 출력합니다.

.*_[0-9]*\.txt다음 패턴 의 파일 목록이 있습니다 .

todo_1.txt
todo_3.txt
todo_91.txt
done_44.txt
done_12000203.txt

파일 이름의 접미사는 항상 으로 끝나지만 _[0-9]*.txt접두사는 가 될 수 있습니다 [a-zA-Z0-9.]*. 가장 큰 숫자를 가진 파일만 출력하고 싶습니다.

todo_91.txt
done_12000203.txt

답변1

$ perl -lne '($prefix,$num) = m/^(.*)_(\d+).*$/;
             if ($num > $n{$prefix}) { $f{$prefix} = $_; $n{$prefix} = $num };
             END { foreach (sort keys %f) { print $f{$_} } }' input.txt 
done_12000203.txt
shopping.list_292.txt
todo_91.txt

이 빠르고 더러운 Perl 해킹은 각 입력 줄에서 파일 이름 접두사와 번호를 분리하고 이를 사용하여 두 개의 해시 배열을 구축합니다. 즉, %n각 파일 이름 접두사의 최대 수를 저장하고 %f관련 파일 이름을 저장합니다. 두 해시 모두 동일한 키(접두사)를 사용합니다.

앞의 모든 내용을 _"접두사"로 캡처하고 그 뒤의 모든 내용 _(줄 끝이나 숫자가 아닌 첫 번째 문자까지)을 숫자로 캡처합니다.

정규식 패턴과 일치하지 않는 줄은 ^(.*)_(\d+).*$완전히 무시됩니다. 원하는 경우 이런 일이 발생하면 경고 메시지를 인쇄할 수 있습니다(독자의 연습 문제로 남겨두기).

입력을 읽으면 %f해시 중 하나의 키를 반복하여 파일 이름을 인쇄합니다.


다음은 독립형 Perl 스크립트와 동일한 약간 더 멋진 버전입니다:

#!/usr/bin/perl

use strict;
my (%f,%n);

while(<>) {
  s/#.*//;          # strip comments (#)
  s/^\s+|\s+$//g;   # strip leading and trailing spaces
  next if (m/^$/);  # ignore blank lines
  chomp;   # strip newline from end of line.

  my ($prefix,$num) = m/^(.*)_(\d+).*$/;

  if ($num > $n{$prefix}) {
    $f{$prefix} = $_;
    $n{$prefix} = $num;
  };
}

foreach (sort keys %f) {
  print $f{$_}, "\n";
}

예를 들어 다른 이름으로 저장하고 find-largest.pl실행 가능하게 만들고 chmod +x find-largest.pl다음과 같이 실행합니다.

$ ./find-largest.pl input.txt 
done_12000203.txt
shopping.list_292.txt
todo_91.txt

관련 정보