행의 일부만 추출하는 방법은 무엇입니까?

행의 일부만 추출하는 방법은 무엇입니까?

grep을 사용하여 airodump-ng의 덤프 파일에서 essid를 추출하고 싶습니다. 제가 추출하고 싶은 부분은 다음과 같습니다.

    <SSID first-time="Wed Feb 25 07:06:57 2015" last-time="Wed Feb 25 07:14:23 2015">
        <type>Beacon</type>
        <max-rate>54.000000</max-rate>
        <packets>3371</packets>
        <beaconrate>10</beaconrate>
        <encryption>WPA2 AES-CCM </encryption>
        <essid cloaked="false">WLAN-123651234</essid>
    </SSID>
    <BSSID>24:65:11:3A:68:02</BSSID>
    <manuf>Unknown</manuf>
    <channel>1</channel>
    <freqmhz>2412 23193</freqmhz>
    <maxseenrate>54000</maxseenrate>
    <packets>

그래서 7번째 줄에서 essid "WLAN-123651234"를 추출하고 싶습니다. 어떻게 해야 하나요? essid의 길이는 중요하지 않습니다. essid에만 이 방법을 사용하는 것이 아니라 다음과 같이 추출해야 하기 때문입니다.

grep >....< dumpfile.netxml
Output: WLAN-1234651234

답변1

grepGNU가 최신 버전의 PCRE 라이브러리(Perl 호환 정규 표현식)에 연결 되면 다음을 시도해 볼 수 있습니다.

$ grep -oP '<essid\b[^<>]*>\K[^<>]*(?=</essid>)' file
WLAN-123651234

그러면 태그의 내용이 추출됩니다 essid.

설명하다:

  • <essid문자열과 정확히 일치<essid

  • \b단어 경계라고 하는 이는 단어 문자와 단어가 아닌 문자 간에 일치하며 그 반대의 경우도 마찬가지입니다.

  • [^<>]*모든 문자와 일치하지만 0회 이상 일치하지 않는 부정 문자 클래스입니다 <.>

  • \K마지막에 인쇄할 때 이전에 일치한 문자를 모두 삭제합니다.

  • [^<>]*모든 문자와 일치하지만 0회 이상 일치하지 않는 부정 문자 클래스입니다 <.>

  • (?=</essid>)정방향 예측 어설션은 일치 항목 뒤에 문자열이 와야 한다고 어설션합니다 </essid>.

답변2

xml 파일에서 콘텐츠를 가져오기 위해 grep을 사용하는 이유는 무엇입니까? grep을 사용하고 있으므로 아마도 Linux 또는 BSD 시스템을 사용하고 있을 것입니다. 그렇다면 명령줄에서 직접 xpath를 사용하는 것은 어떨까요?

xpath -q -e "SSID/essid/text()" /path/to/file.xml

당신이 원하는 것을 정확하게 수행할 것이며, 정규식보다 훨씬 덜 번거롭습니다. 정규식은 XML에서 내용을 가져올 때 매우 취약한 경향이 있습니다.

설치되지 않은 경우 패키지 관리자가 이를 처리할 수 있어야 합니다. 우분투에서는 관련 패키지가 호출됩니다.libxml-xpath-perl.

답변3

GNU grep을 사용하십시오:

grep -oP 'essid.*>\K.*(?=<)' file

산출:

무선랜-123651234

답변4

깨진 레코드처럼 들릴 위험이 있습니다. XMLXML 사양에 관한 한 유효하지만 정규 표현식에 관한 한 완전히 깨뜨릴 수 있는 데이터 구조에 대해 수행할 수 있는 작업이 많이 있습니다. 예를 들어 줄 서식, 들여쓰기, 레이블 줄 바꿈 등이 있습니다.

그러므로 XML로 작업하는 사람이라면 누구나 XML 파서를 사용할 것을 강력히 권장합니다. XML의 중첩 및 처리를 처리하고 서식을 무시하지만 태그, 중첩 및 속성과 같은 중요한 의미를 구별하도록 설계되었습니다.

그래서 나는 당신의 문제에 다음과 같이 접근할 것입니다:

#!/usr/local/bin/perl

use strict;
use warnings;
use XML::Twig;

XML::Twig->new(
    'twig_handlers' => {
        'essid' => sub { print $_ ->text }
    }
)->parse( <> );

이것은 뱉어질 것입니다 :

WLAN-123651234

별도의 스크립트 파일을 갖고 싶지 않다면(하지만 일반적으로 명확성과 유지 관리 측면에서 더 좋기 때문에 그렇게 해야 한다고 생각합니다) 파일을 더 줄일 수 있습니다.

perl -MXML::Twig -e 'XML::Twig->new( twig_handlers => { essid => sub { print $_ -> text,"\n" } } ) -> parse ( <> );' 

보너스 포인트를 얻으려면 다음과 같은 xml xpath 표현식을 사용할 수 있습니다.

essid[@cloaked="false"] 

하위 집합을 인쇄합니다.

또한 유용합니다. XML::Twig이 모듈에는 매우 유용한 xml_grep유틸리티가 함께 제공됩니다. 이 유틸리티는 xml을 grep하므로 필요한 작업을 정확하게 수행합니다.

관련 정보