[재질문] Perl을 이용해 file open해서 그 파일에 대한 내용을 정규식 표현으로 추출을 해서 print할려 합니다.
이전에 같은 질문으로 제가 올렸었는데요.
도저히 답이 안나와서 다시 한번 질문을 드립니다. ㅠㅠ
일단 파일에 내용은
Hostname IP OS/ARC CPU/MEM
1. hostname1 bond0:192.168.0.1 (1000Mb/s) RedHat 5.8 x86_64 E5620@2.40GHz 24GB(2GB)
2. hostname2 bond0:192.168.0.2 (1000Mb/s) RedHat 5.7 x86_64 E5620@2.40GHz 24GB(2GB)
ip를 넣으면 client에 정보가 log파일이 저장 됩니다.(위와 같이 저장이 됩니다.)
이걸 다시 불러와서 정규식 표현으로 추출을 해서 재출력을 하는 방식인데요.
print "Input Slave Server IP :\n"; open my $snoarch, '>', $output; while (my $line = <STDIN>){ last if $line =~ '^f$'; print $snoarch $line; } close $snoarch; print "\n========================================================================================"; print "\nHostname IP OS/ARC CPU/MEM\n"; open $snoarch, '<', $output; while ($s_ip = <$snoarch>){ $telnet->open($s_ip); #$telnet->login($suser,$spw); $telnet->login(@seuser); $telnet->print("su -"); $telnet->waitfor('/password: ?$/i'); $telnet->print($rpw); $telnet->prompt('/# $/'); $telnet->waitfor($telnet->prompt); foreach($i < 50 ) { $i++; } my (@s_host,@s_ip,@snet_d,@s_ethtool,@s_os,@s_arc,@s_cpu,@s_mem,@s_swap); @s_host = $telnet->cmd($host); chomp @s_host; pop @s_host; @s_ip = $telnet->cmd($iff); chomp @s_ip; pop @s_ip; @snet_d = $telnet->cmd($net_dev); chomp @snet_d; pop @snet_d; @s_ethtool = $telnet->cmd($eth_tool); chomp @s_ethtool; pop @s_ethtool; @s_os = $telnet->cmd($os); chomp @s_os; pop @s_os; @s_arc = $telnet->cmd($arc); chomp @s_arc; pop @s_arc; @s_cpu = $telnet->cmd($cpu); chomp @s_cpu; pop @s_cpu; @s_mem = $telnet->cmd($mem); chomp @s_mem; pop @s_mem; @s_swap = $telnet->cmd($swap); chomp @s_swap; pop @s_swap; ##Make a Logfile open my $s_log, '>>', $s_log_file; printf $s_log("$i. %-20s @snet_d:%-16s(@s_ethtool) RedHat %-s%-15s %-5s %-sGB(%-sGB)\n","@s_host","@s_ip","@s_os","@s_arc","@s_cpu","@s_mem","@s_swap"); close $s_log; open (S_FILE, "+<$s_log_file") or die "open failed!\n"; ## 해당 log파일을 open합니다. while (my $line =<S_FILE> ) ##한줄씩 읽어 나가게 while문으로 덮어주고, { my $as5 = /5.8/; ##위 log파일 내용중에 5.8버젼만 추출합니다. if ( $line =~ /^1./) ##처음에는 log파일에 단순히 /5.8/ 요 내용만 가져 갈려 했는데 도저히 답이 안나와서 1. 2. 3. 이런식으로 구분을 라인마다 주었습니다. { my $num = $1; if ( $line =~ /$as5/ ){ ##매칭시킵니다. $num, printf ("%-20s @snet_d:%-16s(@s_ethtool) RedHat %-s%-15s %-5s %-sGB(%-sGB) Matched!\n","@s_host","@s_ip","@s_os","@s_arc","@s_cpu","@s_mem","@s_swap"); ##각각 client에 호스트 네임 / ip / OS / 아키택쳐 등에 정보를 가지고 있는 배열입니다. }else{ $num, printf("%-20s @snet_d:%-16s(@s_ethtool) RedHat %-s%-15s %-5s %-sGB(%-sGB) Does Not Matched!\n","@s_host","@s_ip","@s_os","@s_arc","@s_cpu","@s_mem","@s_swap"); } } close (S_FILE); } } close $snoarch; }
이런식인데,
이걸 어떻게 해야 라인 별로 매칭 시켜서 출력이 가능할까요?
(해당 스크립트 실행 후 결과는 맨 윗라인이 참이면 전부 matched가 되어버리네요 ㅠㅠ)
저대로 실행을 한 결과는
Hostname IP OS/ARC CPU/MEM
hostname1 bond0:192.168.0.1 (1000Mb/s) RedHat 5.8 x86_64 E5620@2.40GHz 24GB(2GB) Matched! ##첫번째 줄
hostname2 bond0:192.168.0.2 (1000Mb/s) RedHat 5.7 x86_64 E5620@2.40GHz 24GB(2GB) Matched! ##두번째 줄
hostname3 bond0:192.168.0.3 (1000Mb/s) RedHat 5.7 x86_64 E5620@2.40GHz 24GB(2GB) Matched! ##세번째 줄
hostname4 bond0:192.168.0.4 (1000Mb/s) RedHat 5.7 x86_64 E5620@2.40GHz 24GB(2GB) Matched! ##네번째 줄
이렇게 전부 Matched가 되어버립니다. 두번째에서 네번째 줄은 5.7버젼이면 Does Not Matched가 출력이 되어야합니다. 아래와 같이요.
제가 원하는 결과는
Hostname IP OS/ARC CPU/MEM
hostname1 bond0:192.168.0.1 (1000Mb/s) RedHat 5.8 x86_64 E5620@2.40GHz 24GB(2GB) Matched!
hostname2 bond0:192.168.0.2 (1000Mb/s) RedHat 5.7 x86_64 E5620@2.40GHz 24GB(2GB) Does Not Matched!
hostname3 bond0:192.168.0.3 (1000Mb/s) RedHat 5.7 x86_64 E5620@2.40GHz 24GB(2GB) Does Not Matched!
hostname4 bond0:192.168.0.4 (1000Mb/s) RedHat 5.7 x86_64 E5620@2.40GHz 24GB(2GB) Does Not Matched!
이렇게 나왔으면 좋겠습니다..ㅠㅠ
그러니까 log파일을 불러와서 첫번째 라인 매치해서 5.8이 맞으면 Matched!가 print되고 다음 두번째 줄 매치한다음 (위예제는 5.7이니) Does Not Matched! 이렇게 print되게 하고
그 다음도 역시 세번째줄 매칭... 이렇게 하는것이 목적입니다. (회사 일 특성상 중요해서요 ㅠ_ㅠ)
고수분들에 의견 부탁드립니다!!
처음에는 log file vs log file로 매칭하려 했는데 이것도 마찬가지더라구요.
p.s raymundo님 저번에 답변 감사했습니다. 근데 제가 원하던 답은 못구해서 이번에 전체 코드를 올려봅니다.
--------------------
행복한 주말 되세요!
1.KLDP 게시판은 답글이 달리면 다시 목록
1.
KLDP 게시판은 답글이 달리면 다시 목록 위로 올라오니까, 한 가지 문제는 한 게시물에서 이어나가시는 게 좋습니다.
2.
어차피 로그 파일이 정말 쓰신 것처럼 저장된다면 매칭은 별개의 문제니까 앞 코드는 딱히 필요는 없어 보입니다만, 그나마도 어째 코드들이 이상한게...
예를 들어 그저 $i를 50까지 증가시키는 무의미한 foreach 루프의 경우는 그냥 $i = 50 하면 되는 거고,
그리고 이 상태라면 로그 파일이 한 줄 쓰일 때마다 로그 파일 전체를 읽으려고 하고 있고, 그나마도 close(S_FILE)이
while 루프 안에 있으니까 로그파일 첫 줄만 읽고 더 읽지 못했을 텐데요.
코드에 공개할 수 없는 부분이 있어 지우는 건 어쩔 수 없는데 최소한 루프나 조건문의 블럭 구조는 정확히 맞춰주셔야 될 것 같습니다.
3.
이제 문제의 매칭 말인데,
일단 로그 파일은 본문에 적어주신 대로 정확히 기록되었다고 하고
지난 번 제 답글의 코드는 정확히 이걸 매치 검사를 하고 있는데요.
출력할 때 라인 내용을 그대로 출력시키고 싶으면 $line 내용만 그대로 다시 출력해주면 될 일이고요.
뭐가 문제인가요?
4.
본문의 코드의 경우는,
그러니 결과적으로 이 모든 오류가 합쳐져서... (코드를 정말로 그대로 옮긴 거라면)
1)로그 파일에 한 줄 추가할 때마다 다시 로그파일을 처음부터 읽어서 매치 여부를 출력하는데
2)오직 로그 파일의 첫줄밖에 안 읽고 있고
3)로그 파일 첫줄은 "1. hostname1 bond0:192.168.0.1 (1000Mb/s) RedHat 5.8 x86_64 E5620@2.40GHz 24GB(2GB)" 이니까 이건 매치가 되는데 (게다가 사실은 뭐가 와도 매치될 것이고)
4)출력할때는 방금 읽은 라인을 출력하지 않고 좀 전에 로그 파일에 추가한 값들을 출력하고 있으니까 마치 두번째, 세번째, 네번째 라인을 읽어서 검사한 것처럼 사용자를 속이고 있는 거죠.
라인 매치가 문제가 아니라 일단 프로그램 흐름부터 다시 검토하시는 게 좋겠습니다.
좋은 하루 되세요!
드디어 해결 된거같습니다!
레이문도님 답변 정말 감사합니다 ㅠㅠ
이제야 답을 찾은듯합니다!!!!
정말정말 감사합니다ㅠㅠㅠㅠㅠㅠㅠㅠ
우선 집에선 서버 환경이 안돼어서 전에 레이문도 님께서 알려주신 방법대로 다시 차근히 해보니 답이 나왔네요 ㅠㅠ
내일 회사 출근해서 다시 차근히 적용 시켜보겠습니다.
금같은 시간 내주시면서 섬세한 댓글 달아주셔서 감사합니다.
-----
늘 행복하시구 건강하세요!!
댓글 달기