2017-12-26 5 views
1

내 시스템에서 실행중인 프로세스 배열을 빌드하려고합니다. 그래서 다음과 같은 두 가지 명령을 사용하는 것을 시도하고있다 할 :Java에서 Windows 작업 목록 출력 구문 분석

tasklist /fo csv /nh  # For a CSV output 
tasklist /nh    # For a non-CSV output 

오전 데 문제 것은 내가 제대로 출력을 구문 분석 할 수 있다는 것입니다.

첫 번째 시나리오

나는이 선 같은 : 나는 "".split(",")을이 프로세스 메모리 사용에 관해서 그러나이 실패하여 구문 분석을 시도

"wininit.exe","584","Services","0","5,248 K" 

-에서 쉼표 숫자 필드 willl 추가 필드가 발생합니다. 나는 그러나이 일이 지금 System Idle Process 같은 과정에서 실패 "".split("\\s+")를 사용하여 분석을 시도하고

wininit.exe     584 Services     0  5,248 K 

:

두 번째 시나리오가 아닌 CSV 출력없이

, 내가 좋아하는 줄이 , 또는 실행 가능한 이름에 공백이있는 다른 프로세스.

같은 분할 인덱스가 항상 올바른 데이터 열을 포함하도록 이러한 출력을 구문 분석 할 수 있습니까?

+0

쉼표로만 구분하는 대신 CSV- 파서를 사용하려고 했습니까? CSV는 일반적으로 잘 정의되어 있으며 좋은 구문 분석기는 따옴표를 올바르게 해석하고 쉼표로 구분하지 않습니다. – cello

+0

가능한 한 적은 수의 외부 라이브러리를 사용하여이 작업을 수행하고 싶습니다. 이 작업은 충분히 간단하며 가장 좋은 접근 방식이 무엇인지 궁금합니다. –

답변

1

문자열을 구문 분석하려면 항상 가장 엄격한 서식을 사용하는 것이 좋습니다. 이 경우 CSV입니다. 이 방법으로 FIVE 그룹을 포함하는 정규 표현식으로 각 행을 처리 할 수 ​​있습니다.

private final Pattern pattern = Pattern 
    .compile("\\\"([^\\\"]*)\\\",\\\"([^\\\"]*)\\\",\\\"([^\\\"]*)\\\",\\\"([^\\\"]*)\\\",\\\"([^\\\"]*)\\\""); 

private void parseLine(String line) { 

    Matcher matcher = pattern.matcher(line); 

    if (!matcher.find()) { 
     throw new IllegalArgumentException("invalid format"); 
    } 

    String name = matcher.group(1); 
    int pid = Integer.parseInt(matcher.group(2)); 
    String sessionName = matcher.group(3); 
    String sessionId = matcher.group(4); 
    String memUsage = matcher.group(5); 

    System.out.println(name + ":" + pid + ":" + memUsage); 
} 
+0

이것은 정확히 내가 찾던 답변의 종류입니다. 예, Java escapement ... 정규식을 조금 어지럽 혀야했습니다. 루비가 아닌 정규 표현식에서 편집하여 내 자신의 편집 내용 중 일부는 완전하고 올바르게 작동합니다. 다시 한 번 감사드립니다! –

+0

당신을 진심으로 환영합니다! –

0

split 대신 StringTokenizer 클래스를 사용해야합니다. " 구분 기호를 사용하고 구분 기호가 반환 될 것으로 예상합니다. 그런 다음 해당 분리 문자를 사용하여 필드 분리를 제공 할 수 있습니다. 예를 들어,

StringTokenizer st = new StringTokenizer(input, "\"", true); 

State state = NONE; 

while (st.hasMoreTokens()) { 
    String t = st.nextToken(); 
    switch(state) { 
     case NONE: 
      if ("\"".equals(t)) { 
      state = BEGIN; 
      } 
      // skip the , 
      break; 
     case BEGIN: 
      // Store t in which entry it correspond to. 
      state = END; 
      break; 
     case END: 
      state = NONE; 
      break; 
    } 
} 

각 토큰은 해당 데이터 세트 내에 저장되므로 각 프로세스에 대해 해당 정보를 처리 할 수 ​​있습니다.

0

시도해 보니 작동하는 것 같습니다.

public void parse(){ 
     try { 
      Runtime runtime = Runtime.getRuntime(); 
      Process proc = runtime.exec("tasklist -fo csv /nh"); 
      BufferedReader stdInput = new BufferedReader(new 
        InputStreamReader(proc.getInputStream())); 
      String line = ""; 
      while ((line = stdInput.readLine()) != null) { 
       System.out.println(); 
       for (String column: line.split("\"")){ 
        if (!column.equals(",")&& !column.equals("")){ 
         System.out.print("["+column+"]"); 
        } 
       } 
      } 
     }catch (Exception e){ 
      e.printStackTrace(); 
     } 
    }