awk를 사용하여 줄을 일치 및 병합하고 Solaris를 사용하여 인쇄

awk를 사용하여 줄을 일치 및 병합하고 Solaris를 사용하여 인쇄

패턴을 맞춰보고 싶어요Solaris 시스템의 경우.

$ luxadm probe 
 No Network Array enclosures found in /dev/es

 Found Fibre Channel device(s): 
 Node WWN:2000000c50f1c8da Device Type:Disk device 
 Logical Path:/dev/rdsk/c1t1d0s2 
 Node WWN:2000000c50f1d9c9 Device Type:Disk device 
 Logical Path:/dev/rdsk/c1t0d0s2

참고 - 사용하려고 하면, 마지막 행에서 한 행을 병합하면 됩니다.

$ luxadm probe |awk '/Node/{n=$2}/Logical/{l=$2} END {print n,l}' 
 WWN:2000000c50f1d9c9 Path:/dev/rdsk/c1t0d0s2

예상되는 출력은 다음과 같습니다.

WWN:2000000c50f1d9c9 Path:/dev/rdsk/c1t0d0s2
WWN:2000000c50f1c8da Path:/dev/rdsk/c1t1d0s2 

답변1

아직 언급되지 않은 짧은 답변awk

awk '/Node/{n=$2; getline; print n " "$2; next}' filename
  • /Node/# 패턴 노드를 찾고 두 번째 필드를 n변수 에 저장합니다.n=$2
  • getline# 다음 줄( Logical줄이 시작되는 곳)로 이동하여 변수에 저장된 내용을 인쇄한 n후 다음 줄의 두 번째 필드를 인쇄합니다.
  • next# 현재 레코드 처리를 중단하고 다음 레코드로 이동합니다.

답변2

실패한 이유는 캡처된 변수를 블록에서 한 번만 인쇄하기 때문입니다 END{}. 이는 마지막 두 개만 인쇄된다는 의미입니다. @Costas는 이미 더 우아한 접근 방식을 제공했지만 몇 가지 작은 변경을 통해 시도한 것과 동일한 논리를 사용할 수도 있습니다.

awk '{ if(/Node/){
        if(length(n)){print n,l} ## if we have an n, print them
        n=$2
        }
        if(/Logical/){l=$2}
      } 
        END {print n,l}' 

또는 다른 도구를 사용할 수 있습니다.

  1. GNU grep/펄

    luxadm probe |  grep -Po '^\s*(Node|Logical)\s*\K.*?(\s|$)' file | 
        perl -lne '$. % 2 ? printf : print'
    
  2. 진주

    luxadm probe |  
      perl -ne 'chomp;if(s/.*(WWN:.*?)\s.*/$1 / || s/.*(Path:.*?)$/$1\n/){print}'
    

답변3

sed나는 당신이 사용해야한다고 생각합니다. 첫째, 일반적으로 성능이 우수하며 awk이 경우 전체적으로 더 간단한 솔루션을 제공합니다.

sed -n 'N;s/Node \([^ ]*\).*Logical/\1/p' <infile

...샘플 데이터를 기반으로 인쇄...

 WWN:2000000c50f1c8da Path:/dev/rdsk/c1t1d0s2
 WWN:2000000c50f1d9c9 Path:/dev/rdsk/c1t0d0s2

읽은 각 줄에 대해 ext sed도 패턴 공간에 N삽입된 줄 구분 기호에 추가됩니다 . \n따라서 위의 s///교체는 두 줄에 걸쳐 있으며 일치하는 항목이 있는 경우 공백으로 구분하여 원하는 두 필드만 인쇄합니다.

sed구문은 모든 POSIX 시스템에 완전히 이식 가능해야 합니다.

답변4

네가 원한다면awk

awk -v RS=' Node ' -v FS=' Logical Path:| ' '/WWN/{print $1,$6}'

기타 (아마 단순)

awk -F":| " '/Node/{printf "%s ", $3":"$4}/Logical Path/{print $4}'

나머지와 함께Path:

awk '/Node/{printf "%s ", $2}/Logical Path/{print $2}'

또는

awk '/Node/{wwn=$2}/Logical Path/{print wwn,$2}'

sed그리고 마지막으로 GNU:

sed -n '/WWN/{s/^\s*\S* *\|\( \S*\)\{3\}\s*$//g;N;s/\n\s*\S*//;p}'

관련 정보