awk 공백을 for 루프 입력으로 바꾸는 방법은 무엇입니까?

awk 공백을 for 루프 입력으로 바꾸는 방법은 무엇입니까?

이것은 샘플 텍스트입니다. (이름은 20210622_090009 입니다)

nvmeSerial      Endpoint        nvmeSpeed           nvmeWidth
================================================================================
nvme0n1         c7:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme1n1         c8:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme2n1         c9:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme3n1         ca:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme4n1         85:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme5n1         86:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme6n1         87:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme7n1         88:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme8n1         41:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme9n1         42:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme10n1        43:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme11n1        44:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme12n1        45:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme13n1        46:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme14n1        47:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme15n1        48:00.0                             Width x2 (downgraded)
nvme16n1        01:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme17n1        02:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme18n1        03:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme19n1        04:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme20n1        05:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme21n1        06:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme22n1        07:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme23n1        08:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme24n1        09:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme25n1        0a:00.0     Speed 32GT/s (ok)       Width x2 (downgraded)

스크립트는 다음과 같습니다.

#! /bin/bash
IFS_old="$IFS"
IFS=$'\n'

for line in $(cat 20210622_090009.txt | tail -n 26 | cut -f 5 | awk '{print $2}' )
do
    echo "$line" 
done
IFS="$IFS_old"
exit 0

스크립트 출력은 다음과 같습니다

8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
32GT/s

속도에 숫자가 있는지 여부에 관계없이 nvmeSpeed(Ex:8GT/s)를 얻고 싶습니다.

보시다시피 nvmeSpeed ​​​​in은 nvme15n1공백입니다.

출력이 표시되지 않습니다.

내 질문은 다음과 같습니다

awk 공백을 for 루프 입력으로 바꾸는 방법은 무엇입니까?

답변1

awk혼자서도 할 수 있습니다. 쉘 스크립트 래퍼가 필요하지 않고, 그런 바로크적인 것도 확실히 필요하지 않습니다 cat 20210622_090009.txt | tail -n 26 | cut -f 5 | awk '{print $2}'. 그리고 모든 곳에서 쉘 읽기 동안 루프를 사용하지 않아야 합니다(또는 awk 또는 Perl 루프와 같은 언어의 출력에 대해 for를 수행하는 것을 피해야 합니다) ) 가능 (참조쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?이유).

경험 법칙: "awk의 출력을 반복하고 싶습니다"라고 생각한다면 "이 작업을 수행하려면 거의 확실히 awk를 사용해야 합니다"로 생각을 바꾸거나 awk 쉘 래퍼에 대한 입력 및 출력 리디렉션을 설정해야 합니다. 일괄 처리 작업. Perl과 대부분의 다른 언어에서도 마찬가지입니다. 다른 언어는 셸보다 작업을 더 잘 수행하며 셸을 사용하려고 하면 작업이 더 어려워질 뿐입니다.

어쨌든 정확히 8개의 열( )이 있는 경우 NF == 8다음 스크립트는 열 4를 인쇄합니다. 열이 8개 미만인 경우( NF < 8) 빈 줄이 인쇄됩니다. 두 경우 모두 각 입력 파일의 시작 부분에 있는 두 헤더 라인을 무시합니다(하나 이상의 파일 이름 인수를 처리할 수 있습니다. FNR < 3 {next}awk에서 NR은 읽은 총 라인 수이고 FNR은 행입니다)현재의문서).

$ awk 'FNR < 3 {next}; NF == 8 {print $4}; NF < 8 {print ""}' 20210622_090009.txt  
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s

8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
32GT/s

답변2

고정 너비 필드가 있는 것 같으므로 FIELDWIDTHS 및 gensub()에 GNU awk를 사용하세요.

$ awk -v FIELDWIDTHS='16 12 24 *' '
    NR>2 {
        gsub(/^ *| *$/,"",$3)
        print gensub(/.* ([^ ]+) .*/,"\\1",1,$3)
    }
' file
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s

8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
8GT/s
32GT/s

위의 내용은 먼저 각 필드의 내용을 너비로 식별합니다.

$ cat file
nvmeSerial      Endpoint        nvmeSpeed           nvmeWidth
================================================================================
nvme0n1         c7:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme1n1         c8:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
nvme15n1        48:00.0                             Width x2 (downgraded)
nvme25n1        0a:00.0     Speed 32GT/s (ok)       Width x2 (downgraded)

$ cat tst.awk
BEGIN { FIELDWIDTHS="16 12 24 *" }
NR != 2 {
    print
    for (i=1; i<=NF; i++) {
        gsub(/^ *| *$/,"",$i)
        print "\t" i, "<" $i ">"
    }
    print "-----"
}

$ awk -f tst.awk file
nvmeSerial      Endpoint        nvmeSpeed           nvmeWidth
        1 <nvmeSerial>
        2 <Endpoint>
        3 <nvmeSpeed>
        4 <nvmeWidth>
-----
nvme0n1         c7:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
        1 <nvme0n1>
        2 <c7:00.0>
        3 <Speed 8GT/s (ok)>
        4 <Width x2 (downgraded)>
-----
nvme1n1         c8:00.0     Speed 8GT/s (ok)        Width x2 (downgraded)
        1 <nvme1n1>
        2 <c8:00.0>
        3 <Speed 8GT/s (ok)>
        4 <Width x2 (downgraded)>
-----
nvme15n1        48:00.0                             Width x2 (downgraded)
        1 <nvme15n1>
        2 <48:00.0>
        3 <>
        4 <Width x2 (downgraded)>
-----
nvme25n1        0a:00.0     Speed 32GT/s (ok)       Width x2 (downgraded)
        1 <nvme25n1>
        2 <0a:00.0>
        3 <Speed 32GT/s (ok)>
        4 <Width x2 (downgraded)>
-----

그런 다음 인쇄할 세 번째 필드 부분을 선택하는 것은 간단합니다. 예를 들어 gensub()나처럼 사용하십시오. 위의 내용은 행에서 누락된 필드, 필드에 단어 수 등에 관계없이 작동합니다.

답변3

또 다른 접근 방식은 고정 너비 필드를 가정합니다(필드 중 하나만 추출하고 비어 있지 않은 경우 항상 6자 "Speed"로 시작한다고 가정합니다).

cut -c35-52 file | sed '1,2d;s/ .*//'

또는 "속도"를 일치시킵니다:

awk -F ' Speed +' 'NR>2 {sub(/ .*/,"",$2); print $2}' file
sed -E '1,2d;s/.* Speed +([^ ]+).*/\1/;t;c\\' file
perl -nE 'say m{\sSpeed\s+(\S+)} if $.>2' file

답변4

 awk 'NR>2{if($4 ~ /^[0-9].*GT/){print $1" =======>" $4}else{if($4 !~ /^[0-9].*GT/){print $1"==================== doesnt contain speed==========================="}}}' filename

산출

nvme0n1 =======>8GT/s
nvme1n1 =======>8GT/s
nvme2n1 =======>8GT/s
nvme3n1 =======>8GT/s
nvme4n1 =======>8GT/s
nvme5n1 =======>8GT/s
nvme6n1 =======>8GT/s
nvme7n1 =======>8GT/s
nvme8n1 =======>8GT/s
nvme9n1 =======>8GT/s
nvme10n1 =======>8GT/s
nvme11n1 =======>8GT/s
nvme12n1 =======>8GT/s
nvme13n1 =======>8GT/s
nvme14n1 =======>8GT/s
nvme15n1==================== doesnt contain speed===========================
nvme16n1 =======>8GT/s
nvme17n1 =======>8GT/s
nvme18n1 =======>8GT/s
nvme19n1 =======>8GT/s
nvme20n1 =======>8GT/s
nvme21n1 =======>8GT/s
nvme22n1 =======>8GT/s
nvme23n1 =======>8GT/s
nvme24n1 =======>8GT/s
nvme25n1 =======>32GT/s

관련 정보