스크립트 파일.awk

스크립트 파일.awk

다음 텍스트 줄을 특정 순서로 정렬하고 싶습니다. 제가 사용한 명령어는 sort공백을 없애고 모든 줄을 공백으로 구분하지 않고 묶어서 알파벳순으로 정리하는 것이었습니다. 각 블록에는 8행의 데이터가 있습니다.

세션: cabSessionID: 052FPBP6Q6X2XGERWHBT
cabLoginID: 053XCDTF8D4J6PD3BG8P
로그인: jack
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-01T01:04:10.899Z
메모리 정보: jsHeapSizeLimit: 2217857988
totalJSHeapSize 사용: 42358792
JHeapSize:36482584

세션: cabSessionID: 052FPBP6Q6X2XGERWHJE
cabLoginID: 053XCDTF8D4J6PD3BG8P
로그인: jack
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-01T01:16:41.558Z
메모리 정보: jsHeapSizeLimit: 2217857988
총 JSHeapSize: 17 775404 0
JSHeapSize 사용: 44842320

메모리 정보: jsHeapSizeLimit: 2217857988
총 JSHeapSize: 45252608
JSHeapSize 사용: 24555080
세션: cabSessionID: 055S75T4QC8JYC4Q0456
cabLoginID: 053XCDTF8D4J6PD3BG8P
로그인: Frank
userAgent: 0
세션시작 시간:2018- 10-23T19:11:11.871Z

나는 최종 결과가 다음과 같기를 원합니다.

로그인: jack
cabLoginID: 053XCDTF8D4J6PD3BG8P
세션: cabSessionID: 052FPBP6Q6X2XGERWHBT
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-01T01:04:10.899Z 메모리 정보: jsHeapSizeLimit: 2217857988
사용된
총 JSHeapSize : 42358792
JHeapSize: 36482584

로그인: jack
cabLoginID: 053XCDTF8D4J6PD3BG8P
세션: cabSessionID: 052FPBP6Q6X2XGERWHJE
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-01T01:16:41.558Z
메모리 정보: jsHeapSizeLimit: 2217857988
총 JSHeapSize: 17 775404 0
JSHeapSize 사용: 44842320

로그인: fred
cabLoginID: 053XCDTF8D4J6PD3BG8P
세션: cabSessionID: 055S75T4QC8JYC4Q0456
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-23T19:11:11.871Z
메모리 정보: jsHeapSizeLimit: 2217857988
총 JS 힙 크기: 4525 2608장
JSHeapSize 사용: 24555080

답변1

하드 코딩된 "순서"를 원하므로 awk가 연관 배열의 각 청크에 대한 데이터를 컴파일한 다음 원하는 순서대로 배열을 인쇄하도록 합니다.

스크립트 파일.awk

BEGIN {
  FS=":"
}

/./ {
  values[$1]=$0
}

/^$/ {
  print values["loginName"]
  print values["cabLoginID"]
  print values["session"]
  print values["userAgent"]
  print values["sessionStartTime"]
  print values["memoryInfo"]
  print values["totalJSHeapSize"]
  print values["usedJSHeapSize"]
  print ""
  delete values
}

END {
  print values["loginName"]
  print values["cabLoginID"]
  print values["session"]
  print values["userAgent"]
  print values["sessionStartTime"]
  print values["memoryInfo"]
  print values["totalJSHeapSize"]
  print values["usedJSHeapSize"]
}

그런 다음 다음을 실행하십시오.

awk -f scriptfile.awk < input

대안으로, 블록 라인의 순서는 신경 쓰지 않지만 여전히 일관된 순서를 유지하고 GNU awk가 있는 경우,

gnuscript.awk

BEGIN {
  FS=":"
  PROCINFO["sorted_in"]="@val_str_asc";
}

/./ {
  values[$1]=$0
}

/^$/ {
  asort(values)
  for (element in values)
    print values[element]
  print ""
  delete values
}

END {
  asort(values)
  for (element in values)
    print values[element]
}

위 스크립트는 각 블록의 행을 알파벳 순서로 인쇄합니다.

cabLoginID:053XCDTF8D4J6PD3BG8P
loginName:jack
memoryInfo:jsHeapSizeLimit:2217857988
session:cabSessionID:052FPBP6Q6X2XGERWHBT
sessionStartTime:2018-10-01T01:04:10.899Z
totalJSHeapSize:42358792
usedJSHeapSize:36482584
userAgent:Mozilla/5.0
...

답변2

단락 모드에서 Perl을 사용하고 해싱을 사용하여 사용자 정의 정렬 순서를 정의할 수 있습니다.

perl -00 -F'\n' -ne '
our %rank; 
BEGIN {
  %rank = (
    loginName => 1,
    cabLoginID => 2,
    session => 3,
    userAgent => 4,
    sessionStartTime => 5,
    memoryInfo => 6,
    totalJSHeapSize => 7,
    usedJSHeapSize => 8
  );
}

%h = ();
map { ($k,$v) = split(/:/, $_, 2); $h{$k} = $v } @F;
for $k (sort { $rank{$a} <=> $rank{$b} } keys %h) { print "$k:$h{$k}\n" };
print "\n";
' file

답변3

일련의 행을 동일한 방식으로 계속해서 정렬하려는 경우 이를 수행할 수 있는 간단한 한 줄 코드는 없다고 생각합니다.

당시 콜론으로 인해 awk가 모든 문자열을 캡처하지 못할까 봐 걱정되었기 때문에 이렇게 빠르고 간단한 쉘 스크립트를 작성했습니다. 실제로는 덩어리별로 정렬됩니다. 블록 내 순서는 printf에 의해 결정됩니다. 필요에 맞게 업데이트하세요.

#!/bin/bash

declare -A arr

(
  while read l; do
    if [[ "" == "${l}" ]]; then
      printf "loginName:%s~cabLoginID:%s~session:%s~userAgent:%s~sessionStartTime:%s~memoryInfo:%s~totalJSHeapSize:%s~usedJSHeapSize:%s~\n" ${arr[loginName]} ${arr[cabLoginID]} ${arr[session]} ${arr[userAgent]} ${arr[sessionStartTime]} ${arr[memoryInfo]} ${arr[totalJSHeapSize]} ${arr[usedJSHeapSize]}
      unset arr
      declare -A arr
      continue
    fi
    k=${l%%:*}
    v=${l#*:}
    arr[${k}]=${v}
  done
  printf "loginName:%s~cabLoginID:%s~session:%s~userAgent:%s~sessionStartTime:%s~memoryInfo:%s~totalJSHeapSize:%s~usedJSHeapSize:%s~\n" ${arr[loginName]} ${arr[cabLoginID]} ${arr[session]} ${arr[userAgent]} ${arr[sessionStartTime]} ${arr[memoryInfo]} ${arr[totalJSHeapSize]} ${arr[usedJSHeapSize]}
) | sort | tr '~' '\n'

exit 0

답변4

또한 시도

awk '
BEGIN   {for (n=split("loginName cabLoginID session userAgent sessionStartTime memoryInfo totalJSHeapSize usedJSHeapSize", T); n; n--) FLSQ[T[n]] = n
        }

        {for (i=1; i<=NF; i++)  {n = split ($i, T, ":")
                                 OUT[FLSQ[T[1]]] = $i
                                }
         for (i=1; i<=NF; i++) $i = OUT[i]
         split ("", OUT)
        }
1
' RS="" ORS="\n\n" FS="\n" OFS="\n"  file
loginName:jack
cabLoginID:053XCDTF8D4J6PD3BG8P
session:cabSessionID:052FPBP6Q6X2XGERWHBT
userAgent:Mozilla/5.0
sessionStartTime:2018-10-01T01:04:10.899Z
memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:42358792
usedJSHeapSize:36482584

.
.
.

BEGIN섹션에서는 각 필드 레이블에 오름차순 숫자를 할당하여 각 레코드 출력의 필드 순서를 정의합니다. 여러 행의 레코드에서 작업할 때 태그를 배열로 분할하면 태그 번호로 색인이 지정된 전체 필드로 배열이 채워집니다 T. OUT레코드를 인쇄하기 전 마지막 작업은 전체 $0(= 레코드)를 재구성하는 것입니다. 모든 필드 및 레코드 구분 기호는 여러 줄의 레코드 레이아웃을 수용해야 합니다.

관련 정보