40 번째 수정본
-  
 - 1. 기본적인 입출력
 
-  
 -  
 - 1.1. 읽기쓰기 모드에서 읽기와 쓰기의 전환
 
-  
 - 1.2. chomp
 
-  
 - 1.3. 인자 3개 형태의 open을 쓰자
 
-  
 - 1.4. 파일핸들도 렉시컬 변수를 쓸 수 있다
 
-  
 
2. <ARGV> 
-  
 - 3. $/
 
-  
 - 4. 파일 핸들끼리의 할당
 
-  
 -  
 - 4.1. 파일 핸들을 서브루틴의 인자로 넘기기
 
-  
 
5. 바이너리 파일 입출력 
-  
 - 6. select
 
-  
 - 7. 버퍼링
 
-  
 - 8. 디렉토리
 
-  
 -  
 - 8.1. chdir
 
-  
 - 8.2. Globbing
 
-  
 - 8.3. Directory Handle
 
-  
 
9. 파일 관련 테스트 연산자 
-  
 - 10. stat, lstat
 
-  
 - 11. special underscore filehandle
 
-  
 - 12. 파일, 디렉토리 관련 명령어와 함수
 
-  
 - 13. 인코딩 지정
 
-  
 - 14. 스트링 변수를 파일처럼 읽거나 쓰기
 
-  
 - 15. 기타
 
-  
 - 16. Comments
 
-  
 
1. 기본적인 입출력
-  open FILEHANDLE, MODE, EXPR
-  EXPR 은 주로 파일명
 -  MODE
-  
< 또는 없음 : 읽기모드
 -  
> : 쓰기모드. 파일이 존재할 경우 내용을 지움
 -  
>> : 추가모드. 파일이 존재할 경우 마지막에 내용을 추가함
 -  
+< : 읽기, 쓰기
 -  
+> : 읽기, 쓰기. 파일이 존재할 경우 내용을 지움
 -  
+>> : 읽기, 추가하기
 -  
|- : 출력 파이프
 -  
-| : 입력 파이프
 
 -  open에 실패하면 $! 변수에 에러 내용이 담긴다.
 
 -  읽거나 쓰고
-  @allLine = <fileHandle>; 파일 전부를 읽기
 -  $aLine = <fileHandle>; 한 줄 읽기
 -  print fileHandle "안녕"; 출력
 
 -  close( fileHandle ); 로 닫는다.
 
한 줄씩 읽는 예제:
open my $fileHandle, "<", $fileName ) or die "Cannot open $fileName: $!";
while( $aLine = <$fileHandle> )
{
  print $aLine;
}
close $fileHandle;
while (<$fileHandle>) {    
  print "$_";
}
배열 변수를 써서 통채로 읽는 예제: (파일이 크면 메모리를 많이 소모할 수 있으므로 주의)
open my $fileHandle, "<", $fileName or die "Cannot open $fileName: $!";
@allLines = <$fileHandle>;
close $fileHandle;
"input record separator" 변수 $/의 값을 바꿈으로써 스칼라 변수에 파일 전체를 담는 경우. ($/의 기본값은 "\n")
local $/ = undef;
open my $fileHandle, "<", $fileName or die "Cannot open $fileName: $!";
$allLines = <$fileHandle>;
close $fileHandle;
파일을 통채로 읽거나 쓰는 것은 
File::Slurp 모듈을 쓰면 편하다.
1.1. 읽기쓰기 모드에서 읽기와 쓰기의 전환
"+<", "+>", "+>>" 를 사용하여 열 경우에, 읽는 동작과 쓰는 동작을 번갈아가며 수행할 경우 예상치 않은 결과가 나올 수 있다([예]) 읽기와 쓰기 동작 사이에는 seek를 써서 제대로 파일포지션 포인터를 세팅해 주어야 하는 듯.
스트링 뒤의 new line "\n"을 제거 정확히는, $/변수의 값을 제거
$line = <STDIN>;
chomp $line;
chomp ($line = <STDIN>);
chomp (@lines = <STDIN>);
1.3. 인자 3개 형태의 open을 쓰자
파일명에 잘못된 문자(부등호 등)가 포함되거나, 악의적으로 파이프 등을 사용하는 것에 대비해서, 인자 3개 형태로 사용하자.
open FH, $filename;       
open FH, "< $filename";   
open FH, "<", $filename;  
1.4. 파일핸들도 렉시컬 변수를 쓸 수 있다
open FH, "<", $filename;      
open my $fh, "<", $filename;  
2. <ARGV>
<ARGV>또는 <> - 명령행 인자로 들어온 스트링을 파일명으로 취급하여 모든 파일들을 열고 읽음. 인자가 없으면 표준입력을 읽음.
현재 읽고 있는 파일의 이름은 $ARGV 에 담긴다.
#!/usr/bin/perl
use warnings;
use strict;
my $lineno;
my $current = "";
while (<>) {
   if ($current ne $ARGV) {
      $current = $ARGV;
      print "\n\t\tFile: $ARGV\n\n";
      $lineno=1;
   }
   print $lineno++;
   print ": $_";
}
-  $/ = ""; - blank line을 구분자로 함 (단락 단위로 읽는다고 볼 수 있다)
 -  $/ = undef; - file 내용 전체를 하나의 스칼라로 읽음
 -  $/ = \1024; (양수의 레퍼런스) - 한 번에 1024바이트를 읽음
 -  chomp 의 역할은 인자의 제일 뒤에 $/ 변수의 값이 있는 경우 그것을 제거
 
4. 파일 핸들끼리의 할당
if (defined $input) {
   open INPUT, $input or die "Couldn't open file $input: $!\n";
} else {
   *INPUT = *STDIN;   
}
4.1. 파일 핸들을 서브루틴의 인자로 넘기기
sub say_hello {
   *WHERE = shift;
   print WHERE "Hi there!\n";
}
say_hello(*STDOUT);
sub say_hello {
   my $fh = shift;  
   print $fh "Hi there!\n";
}
say_hello(*STDOUT); 
5. 바이너리 파일 입출력
binmode FILEHANDLE;
6. select
write나 print 등 출력에 사용되는 디폴트 파일 핸들을 지정하며, 현재의 디폴트 파일 핸들을 반환한다.
select LOG;
print "blah blah...\n";   
select STDOUT;  
select 로 지정된 파일핸들에 대하여
-  $| = 0; - 운영체제의 버퍼링 사용 (기본값)
 -  $| = 1; - 버퍼링 사용하지 않음
 
$| = 1;
for (1...20) {
   print ".";   
   sleep 1;
}
print "\n";
[Suffering from Buffering?] 글도 참고
8. 디렉토리
chdir - working directory 변경
-  변경된 디렉토리는 자식 프로세스에 상속됨
 -  파라메터가 생략되었을 경우는 $_을 쓰는 게 아니라 현재 사용자의 홈 디렉토리로 변경 시도
 -  쉘의 cd에서 가능한 ~username 형식은 지원하지 않는다. - 이것은 OS가 아니라 쉘의 기능
 
8.2. Globbing
Globbing - 파일명 패턴 확장
my @all_files = glob "*";
my @pm_files = glob "*.pm";
my @all_files_including_dot = glob ".* *";  
my @all_files = <*>;
8.3. Directory Handle
opendir로 열고, readdir로 읽고, closedir로 닫는다
-  readdir의 리턴값은 경로명을 제외한 파일명만 들어 있으니 주의
 
opendir DH, "." or die "Couldn't open the current directory: $!";
while ($_ = readdir(DH)) {   
        next if $_ eq "." or $_ eq "..";
        print $_, " " x (30-length($_));
        print "d" if -d $_;
        print "r" if -r _;   
        
}
closedir DH;
}
9. 파일 관련 테스트 연산자
파일 속성 테스트 연산자들
|  File test  |  Meaning  | 
|  -r  |  File or directory is readable by this (effective) user or group  | 
|  -w  |  File or directory is writable by this (effective) user or group  | 
|  -x  |  File or directory is executable by this (effective) user or group  | 
|  -o  |  File or directory is owned by this (effective) user  | 
|  -R  |  File or directory is readable by this real user or group  | 
|  -W  |  File or directory is writable by this real user or group  | 
|  -X  |  File or directory is executable by this real user or group  | 
|  -O  |  File or directory is owned by this real user  | 
|  -e  |  File or directory name exists  | 
|  -z  |  File exists and has zero size (always false for directories)  | 
|  -s  |  File or directory exists and has nonzero size (the value is the size in bytes)  | 
|  -f  |  Entry is a plain file  | 
|  -d  |  Entry is a directory  | 
|  -l  |  Entry is a symbolic link  | 
|  -S  |  Entry is a socket  | 
|  -p  |  Entry is a named pipe (a "fifo")  | 
|  -b  |  Entry is a block-special file (like a mountable disk)  | 
|  -c  |  Entry is a character-special file (like an I/O device)  | 
|  -u  |  File or directory is setuid  | 
|  -g  |  File or directory is setgid  | 
|  -k  |  File or directory has the sticky bit set  | 
|  -t  |  The filehandle is a TTY (as reported by the isatty( ) system function; filenames can't be tested by this test)  | 
|  -T  |  File looks like a "text" file  | 
|  -B  |  File looks like a "binary" file  | 
|  -M  |  Modification age (measured in days)  | 
|  -A  |  Access age (measured in days)  | 
|  -C  |  Inode-modification age (measured in days)  | 
10. stat, lstat
심볼릭 링크의 경우 stat은 링크가 가리키는 파일에 대한 정보를 얻어온다. 링크 자체의 정보를 얻고 싶다면 lstat을 사용
    my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev,
      $size, $atime, $mtime, $ctime, $blksize, $blocks)
        = stat($filename);
11. special underscore filehandle
동일한 파일에 여러 번 파일 테스트 연산자,stat,lstat 연산을 수행하는 경우, "_"를 인자로 주면 기존 연산 시 얻어온 정보를 재사용한다. (서브루틴 등에서 stat을 부르는 바람에 자신도 모르는 사이에 대상 파일이 바뀌었을지 모르니 주의)
push @big_old_files, $_
        if (-s) > 100_000 and -A _ > 90;        
참고: -l _의 경우는 가장 최근에 파일 정보를 얻어온 방법이 lstat이어야만 의미가 있다. stat은 심볼릭 링크의 경우 실제 타겟 파일을 찾아가서 정보를 얻어오므로 -l 연산의 결과가 결코 참이 되지 않기 때문이다. 직전에 수행한 게 lstat 이 아닐 경우 "The stat preceding -l _ wasn't an lstat"라는 에러가 난다.
12. 파일, 디렉토리 관련 명령어와 함수
-  rename OLDNAME, NEWNAME
 -  unlink LIST
 
                   $cnt = unlink ’a’, ’b’, ’c’;
                   unlink @goners;
                   unlink <*.bak>;
-  link OLDFILE, NEWFILE - 하드 링크
 -  symlink OLDFILE, NEWFILE - 심볼릭 링크
-  readlink EXPR - 심볼릭 링크의 값을 읽음
 
 
-  mkdir FILENAME, MASK
 -  rmdir FILENAME
-  빈 디렉토리만 삭제 가능
 -  File::Path 모듈의 rmtree를 쓰면 편하다
 
 
-  chmod LIST
-  ex) chmod 0755, "fred", "barney";
 
 -  chown LIST
-  ex) chown $user, $group, @filenames;
 -  user ID와 group ID는 숫자. 이름으로부터 얻고 싶다면 getpwnam, getgrnam 사용하여 해당 숫자 값을 먼저 얻을 것
 
 -  utime LIST - 액세스 시각과 수정 시각 변경
-  ex) utime $atime, $mtime, @filenames;
 
 
13. 인코딩 지정
파일 입출력 Layer에서 인코딩/디코딩 변환을 지정할 수 있음
open my $fh, '<:utf8', 'file.txt';
open my $fh, '<:encoding(UTF-8)', 'file.txt';
open my $fh, '<:encoding(EUC-KR)', 'file.txt';
open my $fh, '>:utf8', 'file.txt';
binmode STDIN,':utf8';
14. 스트링 변수를 파일처럼 읽거나 쓰기
Perl 5.8 부터 지원
my $string;
open my $fh, ">", \ $string;
open my $fh, ">", \ my $string;
print $fh "Hello";
단, 파일 핸들과 연결되어 있는 상태의 스트링 변수에 다른 형태로 접근할 경우 의도하지 않은 결과가 나오니 주의.
16. Comments
컴퓨터분류