Perl : 파일의 각 줄에서 nth 및 mth를 구분 한 단어 잡기
문제
Nagios에서 모니터링 할 호스트를 추가하는 더 지루한 방법으로 인해 (IP와 Hostname 만 필요했던 이전 프로그램과는 달리 호스트 객체를 정의해야 함), 나는 이것을 자동화하는 것이 가장 좋을 것이라고 생각했습니다. '지금 내가 아는 것은 C/C ++ 및 Java이기 때문에 Perl을 배우기에 좋은 시간이 되십시오.
내가 읽은 파일은 다음과 같습니다.
xxx.xxx.xxx.xxx hostname #comments. i.dont. care. about
내가 원하는 것은 처음 2 개의 캐릭터입니다. 이것들은 분명히 공간이 구분되지만 일반성을 위해서는 무엇이든 일 수도 있습니다. 더 일반적인 것을 만들기 위해, 왜 첫 번째와 세 번째, 네 번째와 10 번가 아닌가? 확실히 Regex 조치가 관련되어 있어야하지만, 만일을 대비하여 그 순간에 그 태그를 남겨 두겠습니다.
해결책
결과를 처리하기 위해 더 많은 Perl을 작성하지 않으면 하나의 라이너가 훌륭합니다.
더 일반적으로, 더 큰 PERL 프로그램의 맥락에서, 당신은 예를 들어 사용자 정규 표현식을 작성합니다.
if($line =~ m/(\S+)\s+(\S+)/) {
$ip = $1;
$hostname = $2;
}
... 또는 당신은 사용합니다 나뉘다 운영자.
my @arr = split(/ /, $line);
$ip = $arr[0];
$hostname = $arr[1];
어느 쪽이든, 논리를 추가하여 유효하지 않은 입력을 확인하십시오.
다른 팁
이것을 코드 골프로 바꾸자! David의 훌륭한 대답을 바탕으로 여기 내 것입니다.
perl -ane 'print "@F[0,1]\n";'
편집 : 실제 골프 제출은 이것처럼 보일 것입니다 (5 스트로크를 깎는) :
perl -ape '$_="@F[0,1]
"'
그러나 그것은이 질문의 목적에 대해서는 덜 읽기 쉬운 것입니다. :-피
다음은 일반적인 솔루션입니다 (코드 골프에서 벗어나면).
#!/usr/bin/perl -n
chop; # strip newline (in case next line doesn't strip it)
s/#.*//; # strip comments
next unless /\S/; # don't process line if it has nothing (left)
@fields = (split)[0,1]; # split line, and get wanted fields
print join(' ', @fields), "\n";
보통 split
공백으로 분할. 그것이 당신이 원하는 것이 아니라면 (예 : 구문 분석 /etc/passwd
), 당신은 구분자를 동선으로 전달할 수 있습니다 :
@fields = (split /:/)[0,2,4..6];
물론, 결장에 세워진 파일을 구문 분석하는 경우, 그러한 파일에 댓글이없고 제거 할 필요가 없을 수도 있습니다.
간단한 1 라이너입니다
perl -nae 'print "$F[0] $F[1]\n";'
구분기를 변경할 수 있습니다 -F
David Nehme가 말했습니다.
perl -nae 'print "$F[0] $F[1}\n";
사용하는 -a
스위치. 나는 그것을 봐야했다 :
-a turns on autosplit mode when used with a -n or -p. An implicit split
command to the @F array is done as the first thing inside the implicit
while loop produced by the -n or -p.
당신은 매일 무언가를 배웁니다. -N은 각 라인을 전달합니다
LINE:
while (<>) {
... # your program goes here
}
그리고 마지막으로 -e
프로그램의 한 줄을 직접 입력하는 방법입니다. 당신은 더 많은 것을 가질 수 있습니다 -e
. 이것의 대부분은 perlrun(1)
인력.
Ray가 물었을 때, 나는 Perl의 암시를 사용하지 않고 내 전체 프로그램을 다시 작성할 것이라고 생각했습니다 (사용을 제외하고 <ARGV>
; 손으로 글을 쓰기가 어렵습니다). 이것은 아마도 파이썬 사람들이 더 행복하게 만들 것입니다 (: Praces에도 불구하고 : -p) :
while (my $line = <ARGV>) {
chop $line;
$line =~ s/#.*//;
next unless $line =~ /\S/;
@fields = (split ' ', $line)[0,1];
print join(' ', @fields), "\n";
}
내가 놓친 것이 있습니까? 바라건대. 그만큼 ARGV
파일 핸들은 특별합니다. 명령 줄의 각 명명 된 파일이 지정되지 않으면 표준 입력을 읽습니다.
편집 : 오, 잊었습니다. split ' '
마법도 마법입니다 split / /
. 후자는 단지 공간과 일치합니다. 전자는 모든 공백과 일치합니다. 이 마법 동작은 패턴이 지정되지 않은 경우 기본적으로 사용됩니다. split
. (일부는 말할 것입니다. 그러나 /\s+/
? ' '
그리고 /\s+/
선의 시작시 공백이 처리되는 방법을 제외하고는 유사합니다. 그래서 ' '
정말 마법입니다.)
이야기의 도덕은 많은 마법의 행동을 좋아한다면 Perl이 훌륭하다는 것입니다. 막대가 없으면 Python을 사용하십시오. :-피
L 행에서 n에서 mth 문자를 찾으려면 L --- 레이블 찾기 예제
@echo off
REM Next line = Set command value to a file OR Just Choose Your File By Skipping The Line
vol E: > %temp%\justtmp.txt
REM Vol E: = Find Volume Lable Of Drive E
REM Next Line to choose line line no. +0 = line no. 1
for /f "usebackq delims=" %%a in (`more +0 %temp%\justtmp.txt`) DO (set findstringline=%%a& goto :nextstep)
:nextstep
REM Next line to read nth to mth Character here 22th Character to 40th Character
set result=%findstringline:~22,40%
echo %result%
pause
exit /b
find label.cmd로 저장하십시오
결과는 드라이브 e 레이블입니다
즐기다