컴퓨터 엑셀 워드 포토샵 구글어스 WINDOWS JAVASCRIPT JAVA C++

 
Tuesday, November 28, 2006

Perl/펄] 파일 속의 문자열, 단어 개수 세기; Count All (grep 확장 스크립트)


울트라에디트의 Find(찾기) 대화상자에 보면 "Count All" 이라는 버튼이 있습니다. 현재 문서에서, 특정 문자열이 몇 개 있는지 모두 세는 것입니다.

그 기능을 펄로 구현해 보았습니다. 유닉스의 문자열 찾기 명령인 grep 에도 이런 기능이 있긴 한데, "문자열이 있는 행의 수"를 셀 수 있을 뿐, 문자열 자체의 개수는 세지 못했습니다. 그래서 직접 이런 스크립트를 만들었습니다.


String/Regex Counter: 문자열/정규식 매치 카운터; 찾은 개수 세기


파일명: countAll.pl
※ 아래 박스 클릭 후, 키보드 화살표 키로 좌우 스크롤 가능함
#!/usr/bin/perl
use strict; use warnings;

  # 옵션 없거나 부족하면 도움말 출력하고 종료
  &help if ($#ARGV < 1);

  my $count = 0;
  my $search = $ARGV[0]; # 1번째 옵션은 찾을 문자열 또는 정규식


  # 2번째 옵션으로 지정해 준, 텍스트 파일 열기
  open IN, "<", "$ARGV[1]" or die "$ARGV[1] : $!\n";

  while (<IN>) { # 1행씩 읽기
    while (/$search/gi) { $count++; } # 현재 행 속에서 단어들 찾기
  }


  print "'$search' : $count Time(s) Matched";

  close IN; # 파일 닫기




sub help { # 도움말 출력 함수
  die <<TEXT;

    Count of matched Word or Regex  (v0.1)


      Usage:
        countAll.pl word <filename>
        countAll.pl regex <filename>

      Example:
        countAll.pl foo test.txt
        countAll.pl \\d+ test.txt

TEXT
}



while (<IN>) {...
이 줄은 실행시 옵션으로 입력해 준 텍스트 파일을 1행씩 읽어, 기본 변수인 $_ 에 넣습니다.


while (/$search/gi) { $count++; }...
이 줄은, 현재 읽은 행에서 $search 변수 속의 단어를 찾고, 만약 단어가 있으면 $count 를 1개 증가시킵니다. 찾는 문자열이 한 행에 여러 개 있으면 계속 카운터가 올라갑니다.




테스트용으로 사용할 test.txt 파일 내용:
foo

foo bar foo foo foo FOO

Foofoo

122 22 11 1000000000

142

771


countAll.pl <찾을 문자열 또는 정규식> <파일명>
순으로 옵션을 입력합니다.


실행 결과:

D:\Z>countAll.pl foo test.txt
'foo' : 8 Time(s) Matched
D:\Z>countAll.pl \d+ test.txt
'\d+' : 6 Time(s) Matched
D:\Z>



대소문자 구분 없이 찾고, Foofoo 이렇게 2개가 연결된 문자열도 2개로 판단합니다.

문자열 대신에 \d+ 이런 정규식으로 찾을 수도 있습니다. \d+ 는 숫자를 모두 찾으라는 것입니다.




현재 코드의 한계:

* 와일드카드는 되지 않고, 1개의 파일 속에서만 문자열을 찾습니다.

* 유니코드 파일을 처리하지 못합니다.





위의 예제 소스의 간단 버전
위의 예제에서는, 명령행에서 실시간으로 외부 데이터 파일명을 입력 받는데,

아래의 소스는,
펄 소스 파일 속에 test.txt 라는 데이터 파일명을 직접 기입하는 방식의 예제입니다. 즉, 외부 파일명 test.txt 를 "하드 코딩"했습니다. 실행 결과는 동일합니다.


#!/usr/bin/perl
use strict; use warnings;

  my $count = 0;
  my $filename = "test.txt"; # 고정된 파일명


  my $search = "foo"; # 찾을 단어.
  # 주의: 여기서 \d+ 라는 정규식을 찾으려면
  # my $search = "\\d+";
  # 이렇게 백슬래쉬(\)를 2중으로 입력해야 함


  # 텍스트 파일 열기
  open IN, "<", $filename or die "$filename : $!\n";

  while (<IN>) { # 1행씩 읽기
    while (/$search/gi) { $count++; } # 현재 행 속에서 단어들 찾기
  }


  print "'$search' : $count Time(s) Matched";

  close IN; # 파일 닫기






File::Slurp 모듈을 이용한 버전


※ 아래 박스 클릭 후, 키보드 화살표 키로 좌우 스크롤 가능함
#!/usr/bin/perl
use strict; use warnings;

use File::Slurp;

### 주의: File::Slurp 모듈이 없는 경우에는
###       https://metacpan.org/release/MUIR/File-Slurp-2004.0904/view/lib/File/Slurp.pm
###       에서 "Slurp.pm" 파일을 다운로드받아서 설치해 주어야 함



  my $count = 0;
  my $filename = "test.txt"; # 고정된 파일명

  my @all_lines;

  my $search = "foo"; # 찾을 단어.
  # 주의: 여기서 \d+ 라는 정규식을 찾으려면
  # my $search = "\\d+";
  # 이렇게 백슬래쉬(\)를 2중으로 입력해야 함


  # 텍스트 파일 열기
  @all_lines = read_file($filename);

  while (<@all_lines>) { # 1행씩 읽기
    while (/$search/gi) { $count++; } # 현재 행 속에서 단어들 찾기
  }


  print "'$search' : $count Time(s) Matched";




▶▶ grep 명령] 찾은 문자열/단어 개수 출력, 행의 개수 출력: Count of String, Linux Unix

단어 수, 200자 원고지 장수, 줄 수 계산기: ▶▶ 단어수 세기, 200자 원고지 매수 계산, 줄수 행 개수; Word Counter




tag: perl
Perl | 펄

4 Comments:
At December 5, 2018 at 1:48 PM, Blogger BOGO said...

미리 파일명을 코드에 설정해놔서 단어만 찾을려면 어떤식으로 수정을해야하죠?

 
At December 5, 2018 at 7:07 PM, Blogger mwultong said...

포스트 본문 끝에, 간단 버전의 펄 소스 코드를 업로드했습니다.

 
At December 6, 2018 at 2:07 PM, Blogger BOGO said...

감사합니다. 혹시 File::Slurp 모듈을 이용한 비슷한 예제도 게시해주실 수 있나요? 저 모듈에 대한 정보가 잘 없네요 ..

 
At December 6, 2018 at 7:13 PM, Blogger mwultong said...

"File::Slurp 모듈을 이용한 버전" 소스를 올려 드렸습니다.

 

Post a Comment

<< Home RSS 2.0 feed

구글 Google 에서 제공하는 무료 블로그 서비스인 블로거 Blogger 의 인터넷 주소는 www.blogger.com 입니다. Blogger 에 블로그를 만들면, blogspot.com 이라는 주소에 블로그가 생성됩니다.
블로그를 직접 방문하지 않고도 최신 게시물을 구독하려면 RSS 2.0 feed 주소를 리더기에 등록하시면 됩니다.
Previous Posts
Monthly Archives
Top