'perl commandline'에 해당되는 글 4건
- 2008.04.17 원라인 펄 놀이 - 첫줄 빼고 sort
- 2007.12.11 여러파일을 sorting 하기
- 2007.11.06 리스트 비교
- 2007.11.05 한꺼번에 많은 파일 지우는 세가지 방법 1
2008. 4. 17. 09:26
원라인 펄 놀이 - 첫줄 빼고 sort
2008. 4. 17. 09:26 in Perl Recipe
#perl 에서 saillinux님과 JEEN님의 "쉘에서 파일의 첫 줄을 빼고 소팅하려면"이라는 대화내용을 듣다가 이를 위한 몇가지 아이디어가 떠롤랐다.
파일의 첫줄을 출력한다 던가 마지막 줄을 출력하는 것은 head나 tail로 쉽게 할 수 있지만 첫 줄을 빼고 출력하는 방법은?
1. 다음과 같은 saillinux 님이 가르쳐 주신 위대한 방법도 있다.
옛날 연구실의 한 선배는 awk 두개를 써서 더블 루프을 구현하기도 했었다.
그러나 다행히도 더 간단한 방법이 있다.
2. tail
간단히 +를 숫자앞에 붙이면 끝이다. 문제는, 이 기능이 언제부터 생긴건지 모르기 때문에 호환성이 좀 걱정된다는 사실.
3. sed
그러나 진정한 강자는 따로 있는 법
4. perl
이제 남은 건 sort 하는 일뿐!! 이건 뭐... 첫줄은 출력하고 나머지는 sort하면 된다.
그러나 여기서 끝내기엔 너무 쉬운 내용을 너무 길게 썼다.
뭔가 더해보자.
소팅하고 출력하는 것을 펄 안에서 끝내보자.
목표는 : 텍스트를 다 배열에 저장하여 첫줄 빼고 소팅한 다음 출력한다.
잘 되긴 하는데,, 뭔가 아쉬운 이 느낌은 뭘까, 너무 당연한 코드라서 재미가 없다.
게다가 매줄마다 push를 하는건,, 너무 비싸다는 생각이!!
모든 줄을 한꺼번에 배열에 넣을 방법은 없을까?
음, 이럴땐 첨부터 꽁수를 생각해보자.
오늘의 새로운 아이디어!!
1. 파일을 읽어서 배열에 넣는 방법
2. perl -ne에서 END{}를 쓰기 귀찮다면 }{를 쓰면 된다.
파일의 첫줄을 출력한다 던가 마지막 줄을 출력하는 것은 head나 tail로 쉽게 할 수 있지만 첫 줄을 빼고 출력하는 방법은?
1. 다음과 같은 saillinux 님이 가르쳐 주신 위대한 방법도 있다.
tail -n `expr \`wc -l file-to-sort | awk '{ print $1 }'\` - 1` file.txt
오.. 왠만한 내공이 아니고는 만들기도 힘든 구문!! `` 안에 ``를 쓰는 센스!!옛날 연구실의 한 선배는 awk 두개를 써서 더블 루프을 구현하기도 했었다.
그러나 다행히도 더 간단한 방법이 있다.
2. tail
tail -n +2 file.txt
언제부턴지는 모르겠지만 tail 에 "앞에서 몇줄부터" 출력해주는 기능이 생겼다. 간단히 +를 숫자앞에 붙이면 끝이다. 문제는, 이 기능이 언제부터 생긴건지 모르기 때문에 호환성이 좀 걱정된다는 사실.
3. sed
sed -n '2,$p' file.txt
오래 전부터 이런 일은 awk, sed 가 강자였지..그러나 진정한 강자는 따로 있는 법
4. perl
perl -ne'$.>1 and print' file.txt
perl -ne'2..-1 and print' file.txt
perl -ne'2..eof and print' file.txt
오.. 가장 "리더블" 하지 않은가!!(물론, $.을 알아야 하지만)perl -ne'2..-1 and print' file.txt
perl -ne'2..eof and print' file.txt
이제 남은 건 sort 하는 일뿐!! 이건 뭐... 첫줄은 출력하고 나머지는 sort하면 된다.
head -1 file.txt; perl -ne'$.>1 and print' file.txt | sort
그러나 여기서 끝내기엔 너무 쉬운 내용을 너무 길게 썼다.
뭔가 더해보자.
소팅하고 출력하는 것을 펄 안에서 끝내보자.
목표는 : 텍스트를 다 배열에 저장하여 첫줄 빼고 소팅한 다음 출력한다.
perl -ne'push @L, $_;END{print $L[0],sort @L[1..$#L];}' file.txt
잘 되긴 하는데,, 뭔가 아쉬운 이 느낌은 뭘까, 너무 당연한 코드라서 재미가 없다.
게다가 매줄마다 push를 하는건,, 너무 비싸다는 생각이!!
모든 줄을 한꺼번에 배열에 넣을 방법은 없을까?
음, 이럴땐 첨부터 꽁수를 생각해보자.
perl -ne'$f=$_;@l=<>;print $f,sort@l;last' file.txt
오옷!! 이거 그럴 듯 하다!! 더 꼬아보자!! perl -ne'@l=<>;last}{print $_,sort@l' file.txt
매우 맘에 드는 코드가 나왔지만, 펄을 새로 시작하는 사람에게는 절대 보여줘선 안될 코드 같다.오늘의 새로운 아이디어!!
1. 파일을 읽어서 배열에 넣는 방법
perl -ne'@L=($_,<>)' file.txt
2. perl -ne에서 END{}를 쓰기 귀찮다면 }{를 쓰면 된다.
perl -ne'push @L,$_ }{ print sort $L'
'Perl Recipe' 카테고리의 다른 글
두 문자열에서 중복되는 부분 찾기 (0) | 2009.03.25 |
---|---|
일전한 글자수의 단어 세기 (7) | 2009.03.24 |
여러파일을 sorting 하기 (0) | 2007.12.11 |
리스트 비교 (0) | 2007.11.06 |
한꺼번에 많은 파일 지우는 세가지 방법 (1) | 2007.11.05 |
2007. 12. 11. 02:39
여러파일을 sorting 하기
2007. 12. 11. 02:39 in Perl Recipe
갑자기 몇개 파일을 소트해야 할 일이 생겨서
하나의 파일을 sort 하는 방법
perl -i.bak -ne'push@L,$_;END{print sort @L;}' filename
여러 파일을 sort하려면
perl -i.bak -ne'push@L,$_;if(eof){print sort@L;@L=();}' file1 file2 file3
또는
for file in file1 file2 file3;do perl -i.bak -ne'push@L,$_;END{print sort@L;}' $file;done
더 좋은 방법은 당장 생각이 안난다.
find를 이용해서 만든 리스트들이 소트되어 있지 않아서 만든 것인데 실제로는 필요없는 디렉토리가 몇개 들어가 있었다. 필요없는 디렉토리들의 공통점은 숫자로 끝나지 않는다는 것이 었기 때문에 간단히
perl -i.bak -ne'/\d$/ or next;push@L,$_;eof and print sort@L and @L=();' input*10k.txt
다시 생각해 보니 펄을 안쓰는게 더 간단하다
for x in input*10k;do grep -v '[0-9]$' $x | sort > $x.tmp;mv $x.tmp $x;done;
이런....
뭐.. 더 빠르겠지 ㅎㅎ
하나의 파일을 sort 하는 방법
perl -i.bak -ne'push@L,$_;END{print sort @L;}' filename
여러 파일을 sort하려면
perl -i.bak -ne'push@L,$_;if(eof){print sort@L;@L=();}' file1 file2 file3
또는
for file in file1 file2 file3;do perl -i.bak -ne'push@L,$_;END{print sort@L;}' $file;done
더 좋은 방법은 당장 생각이 안난다.
find를 이용해서 만든 리스트들이 소트되어 있지 않아서 만든 것인데 실제로는 필요없는 디렉토리가 몇개 들어가 있었다. 필요없는 디렉토리들의 공통점은 숫자로 끝나지 않는다는 것이 었기 때문에 간단히
perl -i.bak -ne'/\d$/ or next;push@L,$_;eof and print sort@L and @L=();' input*10k.txt
다시 생각해 보니 펄을 안쓰는게 더 간단하다
for x in input*10k;do grep -v '[0-9]$' $x | sort > $x.tmp;mv $x.tmp $x;done;
이런....
뭐.. 더 빠르겠지 ㅎㅎ
'Perl Recipe' 카테고리의 다른 글
두 문자열에서 중복되는 부분 찾기 (0) | 2009.03.25 |
---|---|
일전한 글자수의 단어 세기 (7) | 2009.03.24 |
원라인 펄 놀이 - 첫줄 빼고 sort (0) | 2008.04.17 |
리스트 비교 (0) | 2007.11.06 |
한꺼번에 많은 파일 지우는 세가지 방법 (1) | 2007.11.05 |
2007. 11. 6. 15:02
리스트 비교
2007. 11. 6. 15:02 in Perl Recipe
리스트를 비교하는 방법에는 "grep -f", "sort, diff", "comm" 등이 대표적이다.
"grep -f" 는 시간이 너무 오래 걸리는 단점이 있지만 diff, comm등은 강력한 도구이다.
하지막 역시 많은 파일과 복잡한 선택기준 앞에서 나의 가장 강력한 도구는 PERL!!
내가 주로 쓰는 커맨드를 소개한다면
위 예제에서 file1이 $h[1], file0 가 $h[0] 에 저장된다.(file1 과 file0의 순서에 주의)
statement를 위해서 여러가지 상상력을 동원할 수 있다.
간단한 예
file1과 file0에서 123456-1234형태의 패턴(내가 주로 사용하는 런넘버-세그먼트넘버) 을 추출해서 file1과 file0의 공집합의 file1리스트를 출력한다.
비교할 리스트의 성질에 따라 코드는 많이 짧아질 수도 있다.
극단적으로 두 리스트의 똑같은 라인들만 검색하기 위해서는 다음과 같이 할 수도 있다.
"grep -f" 는 시간이 너무 오래 걸리는 단점이 있지만 diff, comm등은 강력한 도구이다.
하지막 역시 많은 파일과 복잡한 선택기준 앞에서 나의 가장 강력한 도구는 PERL!!
내가 주로 쓰는 커맨드를 소개한다면
perl -nle '/(regex)/ and $h[@ARGV]{$1}=$_;END{map{statement;}keys %{$h[0]}}' file1 file0
주의 할 점은 @ARGV(남은 파일 개수)을 인덱스로 사용하기 때문에 인자로 준 파일순서와 인덱스가 거꾸로라는 것.위 예제에서 file1이 $h[1], file0 가 $h[0] 에 저장된다.(file1 과 file0의 순서에 주의)
statement를 위해서 여러가지 상상력을 동원할 수 있다.
간단한 예
perl -nle '/(\d{6}-\d{4})/ and $h[@ARGV]{$1}=$_;END{map{ exists $h[1]{$_} and print $h[1]{$_} }keys %{$h[0]}}' file1 file0
file1과 file0에서 123456-1234형태의 패턴(내가 주로 사용하는 런넘버-세그먼트넘버) 을 추출해서 file1과 file0의 공집합의 file1리스트를 출력한다.
비교할 리스트의 성질에 따라 코드는 많이 짧아질 수도 있다.
극단적으로 두 리스트의 똑같은 라인들만 검색하기 위해서는 다음과 같이 할 수도 있다.
perl -e '@s{`cat OLD`}=( ); exists $s{$_} && print for `cat NEW`' fire1 file2
'Perl Recipe' 카테고리의 다른 글
두 문자열에서 중복되는 부분 찾기 (0) | 2009.03.25 |
---|---|
일전한 글자수의 단어 세기 (7) | 2009.03.24 |
원라인 펄 놀이 - 첫줄 빼고 sort (0) | 2008.04.17 |
여러파일을 sorting 하기 (0) | 2007.12.11 |
한꺼번에 많은 파일 지우는 세가지 방법 (1) | 2007.11.05 |
2007. 11. 5. 20:23
한꺼번에 많은 파일 지우는 세가지 방법
2007. 11. 5. 20:23 in Perl Recipe
원래 펄 사용의 주 목적이 리스트 및 파일 관리였기 때문에 다양한 요구조건에 대해서 가장 효율 적인 방법은 일일이 스크립트파일을 만드는 것 보다 awk, 나 sed 처럼 커맨드라인에서 바로 코드를 만드는 방법이라고 생각하고 있었다. 덕분에 프로그램을 만들때 조금만 길이기 길어져도 헤매는 부작용이 생기기는 했지만.
그 전까지는 그냥 상상력에 의존하여 나름 필요한 코드를 만들어오곤 했었는데 다음 코드를 보고는 그 포스에 감동해버렸다.
한 디렉토리에 지워야 할 파일이 매우 많을때(1024개 이상?)
perl이외에도 방법은 있다.
코드4의 문제는 xargs를 이용하기 때문에 rm을 호출하는 횟수가 더 적어진다.
코드1의 경우 단 하나의 perl 프로세스를 이용하여 파일을 지우기 때문에 이방법이 가장 빠를 것으로 예상할 수있다.
사실 코드4의 xargs 가 코드1의 perl보다 그리 느릴꺼라고 생각하지는 않는다. 적어도 한 프로세스로 100개이상의 파일을 처리할 수 있다면 소모되는 시간은 파일을 삭제 하는데 걸릴 시간이기 때문이다. 게다가 코드1은 사실상 perl의 아름다움을 보여주기 위하여 좀 과장된 측면이 있다. 예를 들어 처리중에 지우지 못하는 파일이 있어도, 혹은 아예 없는 파일이 리스트에 주어져도 아무런 경고를 내지 않는다. 이를 해결하기 위해서 우리는 "die" 나 "print" 또는 "warn"등의 구문을 추가해야한다.
(주의: && and 등의 연산자가 헷갈린다면 언제나 괄호와 if 가 우리 앞에 있음을 있지 말자)
정말 지워야할 파일이 많을 수록. 지워야 할 파일을 선택하는데 기준이 복잡할 수록, 위의 코드 한줄이 점점 짧게 보일 것이다.
그 전까지는 그냥 상상력에 의존하여 나름 필요한 코드를 만들어오곤 했었는데 다음 코드를 보고는 그 포스에 감동해버렸다.
find ./ -name "*.bak" -type f| perl -nleunlink # 코드 1
현재 디렉토리 아래의 모든 *.bak파일을 지우는 코드.한 디렉토리에 지워야 할 파일이 매우 많을때(1024개 이상?)
rm -f *.bak # 코드 2
는 작동하지 않는다. 이때 위의 perl 코드1은 잘 동작한다.(물론 코드1은 하위디렉토리까지 검색한다는 차이는 있다.) perl이외에도 방법은 있다.
find ./ -name "*.bak" -type f -exec rm -f \{\} \; #코드3
find ./ -name "*.bak" -type f | xargs rm -f #코드4
코드3의 문제는 모든 파일마다 rm을 실행하므로 매우 느리다는 데 있다.find ./ -name "*.bak" -type f | xargs rm -f #코드4
코드4의 문제는 xargs를 이용하기 때문에 rm을 호출하는 횟수가 더 적어진다.
코드1의 경우 단 하나의 perl 프로세스를 이용하여 파일을 지우기 때문에 이방법이 가장 빠를 것으로 예상할 수있다.
사실 코드4의 xargs 가 코드1의 perl보다 그리 느릴꺼라고 생각하지는 않는다. 적어도 한 프로세스로 100개이상의 파일을 처리할 수 있다면 소모되는 시간은 파일을 삭제 하는데 걸릴 시간이기 때문이다. 게다가 코드1은 사실상 perl의 아름다움을 보여주기 위하여 좀 과장된 측면이 있다. 예를 들어 처리중에 지우지 못하는 파일이 있어도, 혹은 아예 없는 파일이 리스트에 주어져도 아무런 경고를 내지 않는다. 이를 해결하기 위해서 우리는 "die" 나 "print" 또는 "warn"등의 구문을 추가해야한다.
find ./ -name "*.bak" -type f | perl -nle'unlink or die"Can't remove $_ : $!"'
빠른 방법이라고는 하지만 이제 코드쓰기가 매우 귀찮아졌다. 나라도 xargs가 쓰고싶어 질 것이다. (실제로 그러고 있다.) 하지만 반대로 생각해볼 수 있다. 지우지 못하는 파일에대한 경고를 추가했던 것처럼 우리는 필요한 무엇이든 추가할 수 있다. 텍스트 파일만 지워보자.find ./ -name "*.bak" -type f | perl -nle'-T and unlink or print "Can't remove $_ : $!"
find 의 옵션들을 perl로 옮겨 더욱 강력하게 만들 수도 있다.find | perl -nle '/\.bak$/ && -f && -T and unlink or print "Can't remove $_ : $!"
(파일 테스트 연산자가 제대로 맞는지 잘 기억이...)(주의: && and 등의 연산자가 헷갈린다면 언제나 괄호와 if 가 우리 앞에 있음을 있지 말자)
정말 지워야할 파일이 많을 수록. 지워야 할 파일을 선택하는데 기준이 복잡할 수록, 위의 코드 한줄이 점점 짧게 보일 것이다.
'Perl Recipe' 카테고리의 다른 글
두 문자열에서 중복되는 부분 찾기 (0) | 2009.03.25 |
---|---|
일전한 글자수의 단어 세기 (7) | 2009.03.24 |
원라인 펄 놀이 - 첫줄 빼고 sort (0) | 2008.04.17 |
여러파일을 sorting 하기 (0) | 2007.12.11 |
리스트 비교 (0) | 2007.11.06 |