패턴 일치 후 여러 줄 연결

패턴 일치 후 여러 줄 연결

다음과 같은 데이터가 포함된 파일이 있습니다.

STUDENT DETAILS
NAME MARKS STD
XYZ 20 I
RANK SCHOOL TEACHER GRADE
5 TTT ANON B
POSITION
5
STUDENT DETAILS
NAME MARKS STD
ABC              40                I
RANK SCHOOL TEACHER GRADE
5 TTT ANON A
POSITION
5

내 출력은 다음과 같습니다.

NAME MARKS STD RANK SCHOOL TEACHER GRADE POSITION
XYZ  20     I   5    TTT   ANON    B     5
ABC  40     I   5    TTT   ANON    A     5

STUDENT DETAILSawk패턴을 찾아 두 번째, 다섯 번째, 여덟 번째 행을 인쇄해 보았습니다 . 하지만 선을 연결해야 합니다.

난 달린다:

awk '/STUDENT DETAILS/{nr[NR];nr[NR+2]; nr[NR+5]; nr[NR+8]}; END {for (i in nr) print nr[i]}' file.txt > filenew.txt

이 목표를 어떻게 달성할 수 있나요?

답변1

awk에서는 미리 읽을 수 없으며 패턴을 기억해야 합니다.

awk 파일(아래 u.awk)

/STUDENT/ { li=NR;}
NR == li+2 { mark[li]=$0 }
NR == li+4 { pos[li]=$0 }
END { for (m in mark) printf "%s %s\n",mark[m],pos[m] ;}

어디

  • /STUDENT/ { li=NR;}레코드가 시작되는 줄을 기억하세요
  • NR == li+2 { mark[li]=$0 }현재 동작이 +2일 때 표시를 기억합니다(위치에도 동일).

샘플 데이터로 실행하면(빈 줄을 제거하고 실제 파일에 있는 경우 +2/+4를 조정합니다)

awk -f u.awk liste-1.txt

XYZ 20 I 5 TTT ANON B
ABC              40                I 5 TTT ANON A

헤더 생성이 생략됩니다.

답변2

데이터를 레코드로 미리 분할하는 경우 관련 필드를 인쇄할 필요가 없습니다.

# Pre-splitting
sed '/^STUDENT/ { 1!s/^/\n/; }' infile |

# Reorder the record:
awk -v RS= -v FS='\n' '
  NR == 1 { print $2, $4, $6 }
          { print $3, $5, $7 }'        |

# Pretty-print columns
column -t

산출:

NAME  MARKS  STD  RANK  SCHOOL  TEACHER  GRADE  POSITION
XYZ   20     I    5     TTT     ANON     B      5
ABC   40     I    5     TTT     ANON     A      5

답변3

awk '
    BEGIN { OFS="\t"; maxLines=7 }
    { lineNr=(NR-1) % maxLines + 1; $1=$1; lines[lineNr]=$0 }
    NR == maxLines     { print lines[2], lines[4], lines[6] }
    lineNr == maxLines { print lines[3], lines[5], lines[7] }
' file
NAME    MARKS   STD     RANK    SCHOOL  TEACHER GRADE   POSITION
XYZ     20      I       5       TTT     ANON    B       5
ABC     40      I       5       TTT     ANON    A       5

답변4

Tested with below script and it worked fine


STEP1:

header=`sed '/STUDENT/d' r.txt |sed -n '1~2p'| sort | uniq| sed "N;s/\n/ /g"| sed "N;s/\n/ /g"`

count=`sed '/STUDENT/d'  o.txt|wc -l`
sed -i '/STUDENT/d' o.txt

STEP2:
for ((i=1;i<=$count;i++)); do j=$(($i+5)); sed -n ""$i","$j"p" o.txt| sed -n '2~2p'|sed -r "s/\s+/ /g"|sed "N;s/\n/ /g"|sed "N;s/\n/ /g"; i=$j; done| awk -v header="$header" 'BEGIN{print header}{print $0}'| sed "s/ /\t/g"

관련 정보