-
- 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
컴퓨터분류